问题描述
好的,我在基类中定义了一个依赖属性,我试图在其派生类的构造函数中使用它,但这不起作用,该属性显示为 null.Unity 在使用 container.Resolve() 解析实例后解析依赖属性;
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;
}
这似乎工作正常,但我必须为我所有派生的 ViewModel 这样做..
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; }
....
}
然后我有一个派生类:
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 在解析实例后解析依赖属性容器.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.
您的问题是因为您在构造函数中做的太多.从依赖注入的角度来看,构造函数应该只接受它的依赖(检查它们是否不为空),并将它们存储在私有字段中.做任何比这更多的事情都是反模式.你的构造函数中不应该有任何逻辑.
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 在构造函数中使用的属性依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!