使用Unity的构造函数中使用的属性依赖注入 [英] Property Dependency Injection used in Constructor using Unity

查看:124
本文介绍了使用Unity的构造函数中使用的属性依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我在基类中定义了一个从属属性,并且我试图在其派生类的构造函数中使用它,但这不起作用,该属性显示为null。用container.Resolve();解析实例后,Unity解析从属属性。

Ok, I have a dependent property defined in a base class and I'm trying to use it inside of the constructor of its derived class but that does not work, the property appears as null. Unity resolves the dependent property AFTER resolving an instance with container.Resolve();

我可以选择的另一种方法是将IUnityContainer参数添加到MyViewModel类构造函数中,并将ILogger属性设置为以下形式:

One alternative I have is to add a IUnityContainer parameter to my MyViewModel class constructor and set the ILogger property my self with something like:

public MyViewModel(IUnityContainer container)
{
  Logger = container.Resolve<ILogger>();
}

编辑: @Wiktor_Zychla的另一项建议是将构造函数注入的参数传递为:

Another suggestion by @Wiktor_Zychla is to pass a constructor-injected parameter as:

public MyViewModel(ILogger _logger)
{
    Logger = _logger;
}

这似乎很好,但我必须为我所有的工作做到这一点派生的ViewModels。

This seems to work fine, but I would have to do that for all my derived ViewModels..

但是然后我没有在基类中使用带注释的ILogger依赖项。
请参阅下面的班级示例。问题是:我有哪些替代方案,或者我做错了什么?

But then I'm not using the annotated ILogger dependency in my base class. See my class samples below. The question is: Which alternatives do I have, or what am I doing wrong?

谢谢!

我有一个像这样的ViewModel基类:

I have a ViewModel base class like this:

public abstract class ViewModelBase
{
    [Dependency]
    public ILogger Logger { get; set; }
....
}

然后我有一个派生该类的类:

Then I have a class deriving that:

public class MyViewModel : ViewModelBase
{
    public MyViewModel()
    {
         //I want to use my dependent property in constructor, but doesn't 

         Logger.Error("PRINT AN ERROR");
    }
}

在我的应用程序入口点中,我正在注册ILogger作为单例和MyViewModel类:

And in my application entry point I am registering my ILogger as a singleton and my MyViewModel class:

container.RegisterType<ILogger, MyAppLogger>(new ContainerControlledLifetimeManager());
container.RegisterType<MyViewModel>();


推荐答案


Unity解析从属关系使用
container.Resolve();

Unity resolves the dependent property AFTER resolving an instance with container.Resolve();

解析实例后,这很明显。只需尝试手动执行此操作即可。你不会成功。为了能够注入属性,必须有一个实例,并且拥有一个实例,意味着构造函数已被调用。

Which is quite obvious, if you think about it. Just try to do this manually. You won't succeed. To be able to inject a property, there must be an instance, and having an instance, means the constructor has been called.

您的问题是由于您也这样做而引起的在您的构造函数中。从依赖关系注入的角度来看,构造函数除了接受其依赖关系(请检查它们是否不为null)外,应该将其存储在私有字段中。除此之外,做任何其他事情都是一种反模式。

Your problem is caused because you are doing too much in your constructor. From a dependency injection perspective, a constructor should do nothing more than accept its dependencies (check that they are not null), and store them in private fields. Doing anything more than this is an anti-pattern. You shouldn't have any logic in your constructor.

在构造函数中具有逻辑会使创建对象图不可靠,而构造对象图应该快速且可靠。

Having logic in constructors makes creating the object graph unreliable, while constructing object graphs should be fast and reliable.

遵循这个原则,不会有问题,因为一旦运行任何业务逻辑,您的类就会被完全实例化。由于构造函数只需要设置私有字段,就不会出错,并且没有任何理由调用 Logger.Error( PRINT AN ERROR);

When you follow this principle, there will not be a problem, since once you run any business logic, your class will be completely instantiated. Since the constructor should do nothing more than set private fields, nothing can go wrong and there can't be any reason to call Logger.Error("PRINT AN ERROR"); as you are doing.

这篇关于使用Unity的构造函数中使用的属性依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆