统一:通过构造函数依赖项解析接口实现

本文关键字:接口 实现 函数依赖 统一 | 更新日期: 2023-09-27 18:36:57

我正在尝试了解IoC并确定它是否适合此特定场景。我有以下代码:

public class List { ... }
public class Form { ... }
public interface IService { ... }
public class ListService : IService {
    public ListService(List list) { }
}
public class FormService : IService {
    public FormService(Form form) { }
}
class Program {
    static void Main(string[] args) {
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IService, ListService>(new InjectionConstructor(typeof(List)));
        container.RegisterType<IService, FormService>(new InjectionConstructor(typeof(Form)));
        IService formService = container.Resolve<IService>(new DependencyOverride<Form>(new Form()));
        IService listService = container.Resolve<IService>(new DependencyOverride<List>(new List()));
    }
}

上面的代码显然不起作用,因为IService的第二次注册会覆盖第一个注册。但目的是能够使用构造函数依赖项解析正确的IService实例。我意识到这不是典型的 IoC 场景,而是混合工厂/IoC,我想知道是否可以连接 Unity 以适应这种情况。

编辑结论:
实际问题比上面的例子更复杂。 服务定义对象(列表、窗体)来自 WCF Web 服务。 从那里,系统将构造 IService 实例和一系列其他对象,这些对象最终会导致一组 WPF 视图和视图模型。 一些依赖项在构造函数中明确定义,其他依赖项使用接口作为其构造函数参数。

我的第一个方法是将命名注册与 InjectionConstructor '' SolveParameter 结合使用。 但它很快就会变得相当复杂。 根据 Randy 的建议,我开始使用 Unity 研究汽车工厂。 这是关于该技术的相关帖子。 这是我生成的代码片段

public class Form { }
public class FormService : IService{
    [InjectionConstructor]
    public FormService(Func<string, Form> func, string name):this(func(name)) { }
    public FormService(Form form) { }
}
public class FormDataViewModel {
    public FormDataViewModel(FormService svc) { }
}
public interface IService { }
class Program {
    static Form GetForm(string name) {
        //wcf call
        return new Form();
    }
    static void Main(string[] args) {
        IUnityContainer container = new UnityContainer();
        container.RegisterInstance<Func<string, Form>>(GetForm);
        container.RegisterType<IService, FormService>("form");
        FormDataViewModel vm = container.Resolve<FormDataViewModel>(new DependencyOverride<string>("/system/form/test"));
    }
}

上面的代码在某种意义上是一种混合工厂''IoC 方法。 感谢 Unity 的灵活性。 纯 IoC 不适合我的许多场景。

统一:通过构造函数依赖项解析接口实现

使用

Unity 时,将多个注册与接口关联的唯一方法(开箱即用)是使用命名注册。

在所示方案中(实际方案可能更复杂),这似乎不是问题。 我想你会以某种方式知道你想要什么类型的服务(表格与列表)。

如果场景更复杂,那么您几乎总是可以通过工厂实现您想要的(问题中提到了工厂,所以它似乎很合适)。 有关一些工厂示例,请参阅自动工厂。

基本上,所有适用的IService实例都可以注入到工厂中,工厂可以在运行时(并根据适用的任何条件)确定要返回的适当IService实例。 您甚至可以注入Func<IService>而不是IService来延迟对象创建。