依赖注入的创建模式

本文关键字:模式 创建 注入 依赖 | 更新日期: 2023-09-27 18:14:45

我特别使用c#和Ninject,但问题不仅仅局限于Ninject。我的问题是,我有几个类都有不同的构造函数参数加上注入的。我知道我可以使用kernel.Get<MyObject>(constructor args here)来实例化对象。这对我来说不太合适,因为我把内核弄得到处都是。我将尽力列出下面的例子。

我现在的情况:

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中我可以这样做:

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

但是我感觉不对。我想做的是改变它有一个Initialize方法,但我不确定这是否是最佳实践,或者是否有更好的方法。

可能的新内容:

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);
    }
}

问题:"可能的新东西"是一种常见的做法、坏主意、好主意但执行不力,还是有更好的方法来实现它?

依赖注入的创建模式

你不应该把IStore注入你的DTO。它们应该是普通的对象。相反,将IStore<IThing>注入到当前调用Update的类中,并从那里调用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容器。它们不应该有任何依赖