IoC具有值类型和对象类型依赖性

And*_*dre 8 c# dependency-injection inversion-of-control property-injection constructor-injection

我正在寻找有关为IoC设计对象的最佳方法的建议

假设我有一个对象(Service)依赖于向Ioc注册的DataContext.

但它还需要一个名称属性,我可以像这样设计对象:

class Service
{
    public Service(IDataContext dataContext, 
        string name)
    {
        this._dataContext = dataContext;
        this._name = name
    }

    public string Name
    {
        get
        {
            return _name;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是使用Ioc容器变得非常复杂,因为字符串对象如名称不容易注册,并且Ioc容器的使用变得复杂:因此解决方案变得混乱:

var service = Ioc.Resolve<Service>( ?? )
Run Code Online (Sandbox Code Playgroud)

另一种方法是将其设计如下:

class Service
{
   public Service(IDataContext dataContext)
   {
        this._dataContext = dataContext;
   }

    public string Name { get; set; }
} 
Run Code Online (Sandbox Code Playgroud)

分辨率现在更容易:

var service = Ioc.Resolve<Service>();
service.Name = "Some name";
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是不再需要指定名称.我想听听DI或IoC专家如何设计这个并且仍然对混凝土Ioc容器技术保持相当不可知.

我知道很多取决于你想如何使用它,如果name真的是可选的,选项2将是完美的.但是在需要名称的情况下,你可以在代码的另一个点添加验证步骤,而是去设计使Ioc更简单.

思考?

Mar*_*ann 4

您对 DI 容器的选择不应决定 API 的设计。如果name不是可选的,它应该是构造函数签名的一部分(从而使其成为强制性的)。

下一个问题是如何在不产生大量开销的情况下配置容器。如何做到这一点取决于容器。以下是如何在温莎城堡中围绕字符串参数实现约定:

public class NameConvention : ISubDependencyResolver
{
    public bool CanResolve(CreationContext context,
        ISubDependencyResolver contextHandlerResolver,
        ComponentModel model, DependencyModel dependency)
    {
        return dependency.TargetType == typeof(string)
            && dependency.DependencyKey == "name";
    }

    public object Resolve(CreationContext context,
        ISubDependencyResolver contextHandlerResolver,
        ComponentModel model, DependencyModel dependency)
    {
        return "foo"; // use whatever value you'd like,
                      // or derive it from the provided models
    }
}
Run Code Online (Sandbox Code Playgroud)

NameConvention然后像这样向容器注册:

container.Kernel.Resolver.AddSubResolver(new NameConvention());
Run Code Online (Sandbox Code Playgroud)

如果您的容器没有适当的扩展点,请选择具有适当扩展点的容器。