2016-02-29 120 views
0

我想了解IoC并确定它是否适合这种特定场景。我有以下代码:Unity:通过其构造函数依赖解决接口实现

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,我想知道是否可以连接统一以适应这种情况。

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

我的第一种方法是使用命名注册与InjectionConstructor \ ResolvedParameter相结合。但它很快变得相当复杂。根据兰迪的建议,我开始考虑使用Unity的汽车工厂。这里是技术上的related post。这是我得到的代码片段

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不适合我的许多场景。

+1

我不认为这是可能的。为什么不简单地给每个注册名称?请注意,您可以在没有容器的情况下执行IOC。这被称为[Pure DI](http://blog.ploeh.dk/2014/06/10/pure-di/)。 –

回答

2

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

在您所描述的情况下(实际情况可能会更复杂),似乎并不是这个问题。我想你会以某种方式知道你想要什么类型的服务(Form vs. List)。

如果情景比较复杂,那么你几乎可以总是达到你想要的工厂(工厂在问题中提到,所以它似乎适合)。有些工厂示例请参见Automatic Factories

基本上,IService的所有适用实例都可以注入工厂,并且工厂可以在运行时确定(并根据适用的任何标准)什么是合适的实例返回。您甚至可以注入Func<IService>而不是IService以推迟创建对象。

相关问题