[英]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)
{
}
}
ILifetimeScope
在Autofac 中自動注冊,您無需為其添加注冊。
有關更多信息,請參閱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.