[英]How can I get the instance of a interface from Unity?
我注册了
container.RegisterType<IService, MyService>();
我想创建一个类似于
public class MyHelper
{
private IService _service;
public void SomeMethod
{
_service.RunSomething();
}
}
我真的希望这个_serivce能够神奇地映射到MyService构造函数而不是null,因为我在其他任何地方都找不到IService或Service实例。
如何根据Unity映射使此_service自映射?
您仍然必须将注入的IService
分配给您的实例。 这通常是通过构造函数完成的:
public class MyHelper {
private readonly IService _service;
public MyHelper(IService service) {
_service = service;
}
public void SomeMethod() {
// _service isn't null anymore
}
}
编辑:查看您的评论,我认为您使用的IoC不正确,因此我将尝试填补一些空白。 您不希望创建MyHelper
新实例,因为它所进行的任何创建都必须具有IService
以及MyHelper
引入的任何其他依赖MyHelper
知识。 相反,您可以创建一个工厂来处理创建MyHelper
新实例的MyHelper
,该实例还将处理其依赖项。 这样,您可以设置IoC来解决对此工厂的依赖关系。
public interface IInstanceFactory<out T> {
T Create();
}
public class MyHelperFactory : IInstanceFactory<MyHelper> {
private readonly Func<MyHelper> _myHelperFactory;
public MyHelperFactory(Func<MyHelper> myHelperFactory) {
_myHelperFactory = myHelperFactory;
}
public MyHelper Create() {
return _myHelperFactory();
}
}
因此,我们现在有一个工厂,其中存储有一个Func
,用于创建MyHelper
的实例。 它所做的只是执行我们将在IoC设置中定义的功能。 该功能所MyHelper
就是返回MyHelper
的新实例。
现在,我们可以设置IoC来为我们处理其他所有事情。 因此,在您的IoC设置中,您需要执行以下操作(我不了解Unity,因此我将向您展示使用Autofac。Unity应该能够执行我要显示的所有内容。)
注册服务:
container.RegisterType<MyService>().As<IService>();
注册工厂:(这就是发生魔术的地方)
container.Resolve(b => {
var service = b.Resolve<IService>();
var myHelperFactory = new Func<MyHelper>(() => new MyHelper(service));
return new MyHelperFactory(myHelperFactory);
}).As<IInstanceFactory<MyHelper>>();
在这里,我们获得了一个已经注册为MyService
的IService
实例。 然后,我们创建一个Func<MyHelper>
,后者仅创建一个MyHelper
的新实例,并传递刚刚解析的IService
实例。 最后,我们返回一个新的MyHelperFactory
并将Func<MyHelper>
传递到工厂。
所以可以说我们有Foo
类。 Foo
需要在不了解MyHelper's
依赖项的情况下创建MyHelper
的实例:
public class Foo {
private readonly IMyHelperFactory _factory;
public Foo(IMyHelperFactory factory) {
_factory = factory;
}
public void MethodThatCreatesMyHelper() {
var instance = _factory.Create();
// you now have a valid instance of `MyHelper`
}
}
您要做的最后一件事是从容器中解析Foo
(只要您进行设置):
var fooInstance = container.Resolve<Foo>();
fooInstance.MethodThatCreatesMyHelper();
这是我上面的示例的要点 。 要解决的问题是Foo
可以创建实例MyHelper
而无需任何依赖关系。
一种技术是使用在构造函数中构建 IService
对象的对象初始化MyHelper
。 这可以像lambda表达式一样简单:
public class MyHelper : IMyHelper
{
private Func<IService> _serviceBuilderFunc;
public MyHelper(Func<IService> serviceBuilderFunc)
{
_serviceBuilderFunc = serviceBuilderFunc;
}
public void SomeMethod()
{
var svc = _serviceBuilderFunc();
svc.RunSomething();
}
}
然后在您的统一容器配置中,使用RegisterType()
的重载来指定构造函数参数:
var serviceBuilderFunc = () => new MyService();
container.RegisterType<IMyHelper, MyHelper>(
new InjectionConstructor(serviceBuilderFunc));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.