繁体   English   中英

如何从Unity获取接口实例?

[英]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>>();

在这里,我们获得了一个已经注册为MyServiceIService实例。 然后,我们创建一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM