简体   繁体   English

如何从Unity获取接口实例?

[英]How can I get the instance of a interface from Unity?

I registered 我注册了

container.RegisterType<IService, MyService>();

I want to create a helper class similar to 我想创建一个类似于

public class MyHelper
{
    private IService _service;

    public void SomeMethod
    {
        _service.RunSomething();
    }
}

I really wish this _serivce just magically maps to MyService constructor and not be null, as I have no where to find an IService or Service instance anywhere else. 我真的希望这个_serivce能够神奇地映射到MyService构造函数而不是null,因为我在其他任何地方都找不到IService或Service实例。

How can I make this _service self mapped according to Unity mapping? 如何根据Unity映射使此_service自映射?

You still have to assign the injected IService to your instance. 您仍然必须将注入的IService分配给您的实例。 This is usually done via the constructor: 这通常是通过构造函数完成的:

public class MyHelper {
    private readonly IService _service;

    public MyHelper(IService service) {
        _service = service;
    }

    public void SomeMethod() {
        // _service isn't null anymore
    }
}

Edit: looking at your comment I don't think you're using IoC correctly so I'm going to try to fill in some gaps. 编辑:查看您的评论,我认为您使用的IoC不正确,因此我将尝试填补一些空白。 You don't want to create new instances of MyHelper beacuse whatever creates it will have to have knowledge of IService and any other dependencies MyHelper introduces. 您不希望创建MyHelper新实例,因为它所进行的任何创建都必须具有IService以及MyHelper引入的任何其他依赖MyHelper知识。 Instead, you can create a factory that handles creating new instances of MyHelper which will also handle its dependencies. 相反,您可以创建一个工厂来处理创建MyHelper新实例的MyHelper ,该实例还将处理其依赖项。 This way, you can set up IoC to resolve dependencies on this factory. 这样,您可以设置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();
    }
}

So we now have a factory that stores a Func which is used to create an instance of MyHelper . 因此,我们现在有一个工厂,其中存储有一个Func ,用于创建MyHelper的实例。 All it's doing is executing the function that we will define in the IoC setup. 它所做的只是执行我们将在IoC设置中定义的功能。 All that function does is return a new instance of MyHelper . 该功能所MyHelper就是返回MyHelper的新实例。

Now we can set up IoC to handle everything else for us. 现在,我们可以设置IoC来为我们处理其他所有事情。 So in your IoC setup you'd do the following (I don't know Unity so I'm going to show you using Autofac. Unity should be capable of doing everything I'm showing.) 因此,在您的IoC设置中,您需要执行以下操作(我不了解Unity,因此我将向您展示使用Autofac。Unity应该能够执行我要显示的所有内容。)

Register the service: 注册服务:

container.RegisterType<MyService>().As<IService>();

Register the factory: (this is where the magic happens) 注册工厂:(这就是发生魔术的地方)

container.Resolve(b => {
    var service = b.Resolve<IService>();
    var myHelperFactory = new Func<MyHelper>(() => new MyHelper(service));

    return new MyHelperFactory(myHelperFactory);
}).As<IInstanceFactory<MyHelper>>();

Here we get an instance of IService which we already registered as MyService . 在这里,我们获得了一个已经注册为MyServiceIService实例。 Then we create a Func<MyHelper> who just creates a new instance of MyHelper and passes along the IService instance we just resolved. 然后,我们创建一个Func<MyHelper> ,后者仅创建一个MyHelper的新实例,并传递刚刚解析的IService实例。 Lastly, we return a new MyHelperFactory and pass the Func<MyHelper> into the factory. 最后,我们返回一个新的MyHelperFactory并将Func<MyHelper>传递到工厂。

So lets say we have the class Foo . 所以可以说我们有Foo类。 And Foo needs to create an instance of MyHelper without having any knowledge of MyHelper's dependencies: 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`
    }
}

The last thing you would do is resolve Foo from your container (as long as you set it up): 您要做的最后一件事是从容器中解析Foo (只要您进行设置):

var fooInstance = container.Resolve<Foo>();

fooInstance.MethodThatCreatesMyHelper();

And here is a gist of my example above. 这是我上面的示例的要点 The point to take away is that Foo can create an instance MyHelper without having any knowledge of its dependencies. 要解决的问题是Foo可以创建实例MyHelper而无需任何依赖关系。

One technique is to initialize MyHelper with an object that builds an IService object in the constructor. 一种技术是使用在构造函数中构建 IService对象的对象初始化MyHelper This can be as simple as a lambda expession: 这可以像lambda表达式一样简单:

public class MyHelper : IMyHelper
{
    private Func<IService> _serviceBuilderFunc;

    public MyHelper(Func<IService> serviceBuilderFunc)
    {
        _serviceBuilderFunc = serviceBuilderFunc;
    }

    public void SomeMethod()
    {
        var svc = _serviceBuilderFunc();
        svc.RunSomething();
    }
}

Then in your unity container configuration use the overload of RegisterType() to specify constructor parameters: 然后在您的统一容器配置中,使用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