簡體   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