2015-04-16 44 views
0

当我在下面的代码中解析Reminder时,contactprofile的属性未初始化。我错过了什么?注册的对象属性实例在ioc容器解析后重置

public class Reminder : IReminder 
{ 
    IProfile profile; 
    IContact contact; 
    public Reminder(IProfile profile, IContact contact) 
    { 
     this.profile = profile; 
     this.contact = contact; 
    } 
} 

IProfile profile; 
IContact contact; 
IReminder reminder; 

[TestInitialize] 
public void TestInit() 
{ 
    var container = new UnityContainer(); 

    profile = new Profile() { ID = 1, Active = true }; 
    container.RegisterInstance(profile); 

    contact = new Contact() { ID = 1, Active = true }; 
    container.RegisterInstance(contact); 

    container.RegisterType<IContact, Contact>(new ContainerControlledLifetimeManager()); 
    container.RegisterType<IProfile, Profile>(new ContainerControlledLifetimeManager()); 

    reminder = container.Resolve<Reminder>(); 
} 

当我审视reminder,我希望接触IDActive应分别1和真实的。但我看到它是0和错误的。与profile相同。为什么?

+1

如果这些RegisterInstance调用看起来更像这样:'container.RegisterInstance (profile);'?在这种情况下,你可以跳过'RegisterType'(或者做RegisterType)并跳过'RegisterInstance'。 – DWright

回答

0

你被C#类型推断嘲笑了。你写这样的:

container.RegisterInstance(profile); 

但是C#编译器推断泛型类型是这样的:

container.RegisterInstance<Profile>(profile); 

换句话说,你告诉团结:“请团结,万一有人所需的确切类型的请求'个人资料'(而不是其基本类型或界面),请返回此单个实例“。

Reminder类型但不取决于Profile;这取决于IProfile和你碰巧有注册IProfile如下:

container.RegisterType<IProfile, Profile>(
    new ContainerControlledLifetimeManager()); 

这条线是告诉团结:“万一有人所需的确切类型的IProfile请求,返回那里这情况下被缓存的Profile实例集装箱的寿命。“

由于这是一个完全不同的注册,Unity会为您创建一个实例。你显示的代码可能只是一些玩具代码,但请注意,IoC容器是为了构建服务的对象图;包含应用程序逻辑的应用程序中的类,但没有任何行为。您的ContactPersonReminder类不是服务;他们是实体。它们是您通过服务的对象图推动的状态的一部分。

注入和解析实体(以及其他数据对象,如DTO,消息或命令)将导致您的容器注册中出现很多复杂性和模糊性。例如,问问自己,容器应该返回哪个Profile? ID为1,2,1000的配置文件?它不知道。 DI容器根据类型信息做出决定,原因很简单,它们不适用于创建运行时数据。相反,请解决repositories,command handlers和其他服务。