使用 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
));
或者它是否有效。
由于您需要向 builder.RegisterInstance()
提供容器实例,因此您需要在将其作为参数传递之前对其进行初始化,而您目前并未这样做。但是,如果您构建容器构建器以在注册(和容器初始化)后构建,则可以成功解析 class.
中的容器实例
请注意,这肯定是依赖注入中的设计味道,您绝对不应该这样做。您的 container/kernel 应该只存在于对象图的顶层。如果您开始注入您的容器,您几乎可以肯定正在使用服务定位器反模式。
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 { }
您的代码不安全,因为您在初始化之前注册了一个实例。
如果您需要访问组件内的容器(这不是一个好主意),您可以依赖具有 Resolve
方法的 ILifetimeScope
。
public class ManagmentServiceImp
{
public ManagmentServiceImp(ILifetimeScope scope)
{
}
}
ILifetimeScope
会在 Autofac 中自动注册,您无需为其添加注册。
有关详细信息,请参阅 Autofac 文档中的 Controlling Scope and Lifetime。
顺便说一句,依赖 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 文档中的 Implicit Relationship。
您可以使用此扩展方法:
public static void RegisterSelf(this ContainerBuilder builder)
{
IContainer container = null;
builder.Register(c => container).AsSelf().SingleInstance();
builder.RegisterBuildCallback(c => container = c);
}
这样使用:builder.RegisterSelf();
尝试根据容器解析 IComponentContext ;)
我想知道在自身内部注册容器是否有任何副作用
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
));
或者它是否有效。
由于您需要向 builder.RegisterInstance()
提供容器实例,因此您需要在将其作为参数传递之前对其进行初始化,而您目前并未这样做。但是,如果您构建容器构建器以在注册(和容器初始化)后构建,则可以成功解析 class.
请注意,这肯定是依赖注入中的设计味道,您绝对不应该这样做。您的 container/kernel 应该只存在于对象图的顶层。如果您开始注入您的容器,您几乎可以肯定正在使用服务定位器反模式。
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 { }
您的代码不安全,因为您在初始化之前注册了一个实例。
如果您需要访问组件内的容器(这不是一个好主意),您可以依赖具有 Resolve
方法的 ILifetimeScope
。
public class ManagmentServiceImp
{
public ManagmentServiceImp(ILifetimeScope scope)
{
}
}
ILifetimeScope
会在 Autofac 中自动注册,您无需为其添加注册。
有关详细信息,请参阅 Autofac 文档中的 Controlling Scope and Lifetime。
顺便说一句,依赖 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 文档中的 Implicit Relationship。
您可以使用此扩展方法:
public static void RegisterSelf(this ContainerBuilder builder)
{
IContainer container = null;
builder.Register(c => container).AsSelf().SingleInstance();
builder.RegisterBuildCallback(c => container = c);
}
这样使用:builder.RegisterSelf();
尝试根据容器解析 IComponentContext ;)