4

나는 특별히 Ninject와 함께 C#을 사용하고 있지만 문제는 Ninject를 넘어서 있습니다. 내 문제는 내가 다른 생성자 인수와 주입 된 것들을 가진 몇 개의 클래스를 가진다는 것이다. 내가 kernel.Get<MyObject>(constructor args here) 개체를 인스턴스화하는 데 사용할 수 있습니다. 이것은 내가 온통 커널을 가지고 있기 때문에 나에게 맞는 느낌이 들지 않는다. 아래에 예를 나열하기 위해 최선을 다할 것입니다.의존성 주입을위한 창조적 인 패턴

내가 지금 무엇을 가지고 :

kernel.Get<Car>(new ConstructorArgument("key", 1), new ConstructorArgument("year", 2010), new ConstructorArgument("make", "Astin Martin"), new ConstructorArgument("model", "Vanquish")); 

하지만 바로 나에게 생각하지 않습니다

public interface IStore<T> 
{ 
    void CommitToDatabase(T item); 
} 

public abstract class Thing 
{ 
    private IStore<Thing> _store; 

    protected Thing(object key, IStore<Thing> store) 
    { 
     Key = key; 
     _store = store; 
    } 

    public object Key { get; private set; } 

    public virtual void Update() 
    { 
     _store.CommitToDatabase(this); 
    } 
} 

public class Person :Thing 
{ 
    public Person(object key, string name, int age, IStore<Thing> store) 
     : base(key, store) 
    { 
     Name = name; 
     Age = age; 
    } 

    public string Name { get; private set; } 
    public int Age { get; private set; } 
} 

public class Car :Thing 
{ 
    public Car(object key, int year, string make, string model, IStore<Thing> store) 
     : base(key, store) 
    { 
     Year = year; 
     Make = make; 
     Model = model; 
    } 

    public int Year { get; private set; }  
    public string Make { get; private set; } 
    public string Model { get; private set; } 
} 

나는 내가 다음과 같은 작업을 수행 할 수 Ninject에 알고. 내가 뭘 생각하고 초기화 방법을 가지고 그것을 변경하는 것이지만, 이것이 최선의 연습 또는 더 좋은 방법이 있는지 모르겠습니다.

가능한 새로운 물건 :

public interface IStore<T> 
{ 
    void CommitToDatabase(T item); 
} 

public abstract class Thing 
{ 
    private IStore<Thing> _store; 

    protected bool _isInitialised; 

    protected Thing(IStore<Thing> store) 
    { 
     Key = null; 
     _store = store; 
     _isInitialised = false; 
    } 

    public object Key { get; private set; } 

    public virtual void Initialize(object key) 
    { 
     if (!_isInitialised) { 
      Key = key; 
      _isInitialised = true; 
     } 
    } 

    public virtual void Update() 
    { 
     _store.CommitToDatabase(this); 
    } 

    protected bool IsInitialised() 
    { 
     return _isInitialised; 
    } 
} 

public class Person :Thing 
{ 
    public Person(IStore<Thing> store) 
     : base(store) 
    { 
     Name = string.Empty; 
     Age = int.MinValue; 
    } 

    public string Name { get; private set; } 
    public int Age { get; private set; } 

    public void Initialize(object key, string name, int age) 
    { 
     if (!base.IsInitialised()) { 
      Name = name; 
      Age = age; 
     } 

     base.Initialize(key); 
    } 
} 

public class Car :Thing 
{ 
    public Car(IStore<Thing> store) 
     : base(store) 
    { 
     Year = 0; 
     Make = "Ford"; 
     Model = "Model T"; 
    } 

    public int Year { get; private set; } 
    public string Make { get; private set; } 
    public string Model { get; private set; } 

    public void Initialize(object key, int year, string make, string model) 
    { 
     if (!base.IsInitialised()) { 
      Year = year; 
      Make = make; 
      Model = model; 
     } 

     base.Initialize(key); 
    } 
} 

질문 : 은 '가능한 새로운 물건'일반적인 관행, 나쁜 생각, 가난한 구현 좋은 생각인가, 또는 모두를 할 수있는 더 좋은 방법이 ?

+0

먼저 엔티티에 지속성 메커니즘을 알리는 것이 바람직하지 않다고 생각합니다. 리포지토리 패턴을 대신 사용하는 방법을 생각해보십시오. – tvanfosson

답변

6

DTt에 IStore를 주입하면 안됩니다. 그들은 평범한 물건이어야합니다. 대신 현재 Update을 호출하는 클래스에 IStore<IThing>을 삽입하고 거기에서 CommitToDatabase을 호출하십시오.

public class PersonService 
{ 
    private readonly IStore<Person> store; 
    public PersonService(IStore<Person> store) 
    { 
     this.store = store; 
    } 

    public void CreatePerson(string name, int age) 
    { 
     var person = new Person(name, age); 
     this.store.CommitToDatabase(person); 
    } 
} 

또한 Person과 같은 DTO는 IoC 컨테이너를 사용하여 만들어서는 안됩니다. 그것들을 당신의 영속 계층에서 얻고, AutoMapper를 사용하여 생성하거나 new을 사용하여 생성하십시오. 그러나 IoC 컨테이너를 사용하지 마십시오. 그들은 어떤 의존성도 없어야합니다.

관련 문제