C# 使用Autofac注册容器本身
我想知道在容器内部注册是否有任何副作用C# 使用Autofac注册容器本身,c#,inversion-of-control,autofac,ioc-container,C#,Inversion Of Control,Autofac,Ioc Container,我想知道在容器内部注册是否有任何副作用 IContainer container; ContainerBuilder builder = new ContainerBuilder(); container = builder.Build(); builder.RegisterInstance(container).As<IContainer>(); i集装箱; ContainerBuilder=新的ContainerBuilder(); container=builder.Buil
IContainer container;
ContainerBuilder builder = new ContainerBuilder();
container = builder.Build();
builder.RegisterInstance(container).As<IContainer>();
i集装箱;
ContainerBuilder=新的ContainerBuilder();
container=builder.Build();
builder.RegisterInstance(container.As();
然后他们就这样使用它
builder.RegisterType<IManagmentServiceImp>().As<ManagmentServiceImp>()
.WithParameter(new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IContainer) && pi.Name == "Container",
(pi, ctx) => container
));
builder.RegisterType().As()
.WithParameter(新解析参数(
(pi,ctx)=>pi.ParameterType==typeof(IContainer)和&pi.Name==“容器”,
(pi,ctx)=>容器
));
或者它是否会工作。由于您需要向
builder.RegisterInstance()
提供容器实例,因此需要在将其作为参数传递之前对其进行初始化,而您目前没有这样做。但是,如果将容器生成器构造为在注册(和容器初始化)后生成,则可以成功解析类中的容器实例
请注意,这肯定是依赖项注入中的一种设计味道,您绝对不应该这样做。容器/内核应该只存在于对象图的顶层。如果您开始注入容器,几乎可以肯定,您正在走向服务定位器反模式
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 { }
void Main()
{
IContainer container=newcontainerbuilder().Build();
ContainerBuilder=新的ContainerBuilder();
builder.RegisterInstance(container.As();
builder.RegisterType().As()
.WithParameter(新解析参数(
(pi,ctx)=>pi.ParameterType==typeof(IContainer)和&pi.Name==“容器”,
(pi,ctx)=>容器
));
container=builder.Build();
var instance=container.Resolve();
}
公共类ManagementServiceImp:ImanagementServiceImp
{
私人集装箱;
公共管理服务IMP(IContainer容器)
{
_容器=容器;
_container.Dump();
}
}
公共接口IManagmentServiceImp{}
您的代码不安全,因为您在初始化实例之前注册了它
如果您需要访问组件内部的容器(这不是一个好主意),您可以依赖具有Resolve
方法的ILifetimeScope
public class ManagmentServiceImp
{
public ManagmentServiceImp(ILifetimeScope scope)
{
}
}
ILifetimeScope
在Autofac中自动注册,您无需为其添加注册
有关更多信息,请参阅Autofac文档中的
顺便说一下,依赖IoC容器不是一个好的做法。看起来你使用了反模式。如果需要容器来延迟加载依赖项,则可以将composition与Func
或lazy
公共类管理服务导入
{
公共管理服务IMP(Lazy myService)
{
这个._myService=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()代码>@torvin容器以何种方式未配置?以何种方式无法解决OP的需要?抱歉,我无意中删除了我的评论。它是“这是错误的,它将注册一个未配置的容器”@torvin您还没有解释这如何无法满足OP的需要。容器将是未配置的,因为当您分配新容器container=builder.Build()时代码>生成器仍将保留对上一个空容器(由新的ContainerBuilder().Build()创建)的引用。您需要使用Register(Func)
(请参阅我的答案)而不是RegisterInstance
使用此方法,我得到指定的CGI应用程序遇到错误,服务器在webapi core中的第一个请求后终止了进程,此后服务器无法处理请求。更改为ILifetimeScope解决了Autofac 5.0的问题,该功能不再有效-更改了.RegisterBuildCallBack()
的签名,现在提供了ILifetimeScope
而不是IContainer
。我仍在寻找一个可行的修复方法。IContainer
继承自ILifetimeScope
所以我的作品中有一个演员阵容。。。
public static void RegisterSelf(this ContainerBuilder builder)
{
IContainer container = null;
builder.Register(c => container).AsSelf().SingleInstance();
builder.RegisterBuildCallback(c => container = c);
}