[英]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.