簡體   English   中英

使用 Autofac 注冊容器本身

[英]Register Container Itself Using Autofac

我想知道在其內部注冊容器是否有任何副作用

IContainer container;
ContainerBuilder builder = new ContainerBuilder();
container = builder.Build();
builder.RegisterInstance(container).As<IContainer>();

並且像這樣使用它

builder.RegisterType<IManagmentServiceImp>().As<ManagmentServiceImp>()
    .WithParameter(new ResolvedParameter(
            (pi, ctx) => pi.ParameterType == typeof(IContainer) && pi.Name == "Container",
            (pi, ctx) => container
));

或者它是否會起作用。

您的代碼不安全,因為您在初始化之前注冊了一個實例。

如果您需要訪問組件內的容器(這不是一個好主意),您可以依賴具有Resolve方法的ILifetimeScope

public class ManagmentServiceImp 
{
    public ManagmentServiceImp(ILifetimeScope scope)
    {
    }
}

ILifetimeScopeAutofac 中自動注冊,您無需為其添加注冊。

有關更多信息,請參閱Autofac文檔中的控制范圍和生命周期

順便說一句,依賴您的 IoC 容器不是一個好習慣。 看起來您使用了Service Locator反模式。 如果您需要容器延遲加載依賴項,您可以使用帶有Func<T>Lazy<T>

public class ManagmentServiceImp 
{
    public ManagmentServiceImp(Lazy<MyService> myService)
    {
        this._myService = myService; 
    }

    private readonly Lazy<MyService> _myService;
}

在這種情況下,將在您第一次訪問時創建MyService

有關更多信息,請參閱Autofac文檔中的隱式關系

您可以使用此擴展方法:

public static void RegisterSelf(this ContainerBuilder builder)
{
    IContainer container = null;
    builder.Register(c => container).AsSelf().SingleInstance();
    builder.RegisterBuildCallback(c => container = c);
}

像這樣使用它: builder.RegisterSelf();

由於您需要向builder.RegisterInstance()提供容器的實例,因此您需要在將其作為參數傳遞之前對其進行初始化,而您目前沒有這樣做。 但是,如果您將容器構建器構建為在注冊(和容器初始化)之后構建,則可以成功解析類中的容器實例。

請注意,這肯定是依賴注入中的一種設計味道,您絕對不應該這樣做。 您的容器/內核應該只存在於對象圖的頂層。 如果您開始注入您的容器,您幾乎可以肯定正在使用 Service Locator Anti-Pattern。

void Main()
{
    IContainer container = new ContainerBuilder().Build();
    ContainerBuilder builder = new ContainerBuilder();

    builder.RegisterInstance(container).As<IContainer>();

    builder.RegisterType<ManagementServiceImp>().As<IManagmentServiceImp>()
       .WithParameter(new ResolvedParameter(
            (pi, ctx) => pi.ParameterType == typeof(IContainer) && pi.Name == "Container",
            (pi, ctx) => container
    ));

    container = builder.Build();
    var instance = container.Resolve<IManagmentServiceImp>();
}

public class ManagementServiceImp : IManagmentServiceImp 
{ 
    private IContainer _container;

    public ManagementServiceImp(IContainer Container)
    {
        _container = Container;
        _container.Dump();
    }
}

public interface IManagmentServiceImp { }

嘗試針對容器解析 IComponentContext ;)

雖然我沒有回答你的問題。 嘗試在服務類中獲取容器的句柄或者除了相當於IModule之外的任何東西都是代碼味道。

您的服務代碼不應該了解IOC IMO。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM