1

EF Linq context.Entities.Select(x => new Y {...})投影から返されたオブジェクトに依存関係を挿入する方法はありますか? (これはただの構文エラー/不備のため申し訳ありませんが、コンパイルされていない、でタイプされる)Entity Frameworkエンティティとプロジェクトへの依存性注入

// person MAY be an entity, but probably more likely a class to serve a purpose 
public class Person { 
    public string Name 
    public DateTime DOB {get;set; } 

    // what I want to achieve: note, I don't want to have complex logic in my model, I want to pass this out to a Service to determine.. obviously this example is over simplified... 
    // this could be a method or a property with a get accessor 
    public bool CanLegallyVote() 
    { 
    return _someServiceThatWasInjected.IsVotingAge(this.DOB); 
    } 

    private readonly ISomeService _someServiceThatWasInjected; 
    public Person (ISomeService service) 
    { 
    _someServiceThatWasInjected = service; 
    } 
} 

// then calling code... I can't pass ISomeService into the "new Person", as "Additional information: Only parameterless constructors and initializers are supported in LINQ to Entities." 

// If the above model represents a non-entity... 
var person = context.People.Select(person => new Person {Name = x.Name, DOB = x.DateOfBirth}).First; 
// OR, if the above model represents an EF entity... 
var person = context.People.First(); 

if (person.CanLegallyVote()) {...} 

// I don't want to invoke the service from the calling code, because some of these properties might chain together inside the model, I.e. I do not want to do the following: 
if (_service.CanLegallyVote(person.DOB)) 

は次のとおりです。私が達成しようとしているものの

ソートを(私はシンプルインジェクタを使用していますが、概念は残っています) Linq/Entity Frameworkには、オブジェクトを(DIを介して)作成されたモデルに渡すことができるフックがありますか?

答えて

5

イベントはObjectContext.ObjectMaterializedです。あなたはそれをフックすることができます。しかし、ドメインエンティティにドメインサービスを注入するのは良い考えではありません。あなたはこのテーマに関する多くの記事を見つけることができます。

4

@Oryolは、the other way aroundのように、構築中にドメインオブジェクトにアプリケーションコンポーネントを注入するのが正しいです。is a bad ideaです。

1つの解決策は、コンストラクタインジェクションの代わりにメソッドインジェクションを使用することです。つまり、各ドメインメソッドはメソッド引数として必要なサービスを定義します。例:

public bool CanLegallyVote(ISomeService service) { ... } 
+0

私のLinqクエリは、必ずしもドメインオブジェクトではないモデルに投影を返しています。私はクライアントに送るためにオブジェクトをシリアル化したいと思っています。私の考えでは、シリアル化の前にエンティティを「処理する」必要がないのは良いことです。何かのようなもの(C#6の構文) 'public bool CanLegallyVote => _service.CanLegallyVote(this.DOB)'は、それがただ直列化することを意味します。しかし、それは悪い設計と見なされるならば、私はそれをする他の方法を考慮する必要があります/する必要があります。 – AndrewP

+0

リポジトリとアダプタパターンに関する.Net Junkieリンクの例が最も近い例です。私は自分の "人"モデルに "CanLegallyVote"というプロパティを持たせたいが、それはその意味を実装することには関係しない。私の考えは、それがパラメータを取り、ブールを返すサービスになるということです。今、私はこれを単純なメソッド呼び出しとして行うことができましたが、それはオブジェクトをシリアライズするだけでは意味がないことを意味します。おそらく私のためのより良い設計は、人をとり、評価し、直列化可能な文字列を返すクラスを持つことでしょうか? – AndrewP

+0

@AndrewP:私の経験では、行動やデータの分離に努めなければならないということです。プロジェクションや他のDTOにロジックが含まれている場合、特に依存関係がある場合は、アプリケーションが複雑になります。 IMOは何をするべきなのでしょうか?投影中にCanLegallyVote値をあらかじめ計算しておくことです。 (Person => new PersonDto {Name = x.Name、CanLegallyVote = _service.CanLegallyVote(person .DOB)}); ' – Steven