在静态类中访问或获取Autofac容器 [英] Access or get Autofac Container inside a static class
问题描述
我需要在静态类中获取或访问我的IoC容器.这是我的(简化)方案:
I need to get or access to my IoC container in a static class. This is my (simplified) scenario:
我在Startup类中注册了ASP .net Web Api的依赖项(但是我也对MVC或WCF进行了注册.我有一个DependecyResolver项目,但是为简单起见,请考虑以下代码)
I register dependencies for ASP .net Web Api in a Startup class (but also I do this for MVC or WCF. I have a DependecyResolver project, but for simplicity, consider the following code)
// Web Api project - Startup.cs
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
var builder = new ContainerBuilder();
// ... Omited for clarity
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.AsClosedTypesOf(typeof(IHandle<>))
.AsImplementedInterfaces();
// ...
IContainer container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ...
}
然后,在一个单独的类库中,我有我的静态类(为简化起见,再次简化):
Then, in a separate class library I have my static class (again simplified for clarity):
public static class DomainEvents
{
private static IContainer Container { get; set; }
static DomainEvents()
{
//Container = I need get my Autofac container here
}
public static void Register<T>(Action<T> callback) where T : IDomainEvent { /* ... */ }
public static void ClearCallbacks() { /* ... */ }
public static void Raise<T>(T args) where T : IDomainEvent
{
foreach (var handler in Container.Resolve<IEnumerable<IHandle<T>>>())
{
handler.Handle(args);
}
// ...
}
}
任何想法我怎么能得到这个?
Any idea how can I get this?
推荐答案
我需要在静态类中获取或访问我的IoC容器. 你知道我怎么能得到这个吗?
I need to get or access to my IoC container in a static class. Any idea how can I get this?
是的,你没有!严重地.带有静态DomainEvents
类的模式源自Udi Dahan,但即使Udi也承认这是一个错误的设计.需要自己依赖的静态类非常难以使用.它们使系统难以测试和维护.
Yes, you don't! Seriously. The pattern with the static DomainEvents
class originates from Udi Dahan, but even Udi has admitted that this was a bad design. Static classes that require dependencies of their own are extremely painful to work with. They make the system hard to test and maintain.
相反,创建一个IDomainEvents
抽象并将该抽象的实现注入到需要发布事件的类中.这样可以完全解决您的问题.
Instead, create a IDomainEvents
abstraction and inject an implementation of that abstraction into classes that require publishing events. This completely solves the your problem.
您可以按以下方式定义DomainEvents
类:
You can define your DomainEvents
class as follows:
public interface IDomainEvents
{
void Raise<T>(T args) where T : IDomainEvent;
}
// NOTE: DomainEvents depends on Autofac and should therefore be placed INSIDE
// your Composition Root.
private class AutofacDomainEvents : IDomainEvents
{
private readonly IComponentContext context;
public AutofacDomainEvents(IComponentContext context) {
if (context == null) throw new ArgumentNullException("context");
this.context = context;
}
public void Raise<T>(T args) where T : IDomainEvent {
var handlers = this.context.Resolve<IEnumerable<IHandle<T>>>();
foreach (var handler in handlers) {
handler.Handle(args);
}
}
}
您可以按以下步骤注册此类:
And you can register this class as follows:
IContainer container = null;
var builder = new ContainerBuilder();
builder.RegisterType<AutofacDomainEvents>().As<IDomainEvent>()
.InstancePerLifetimeScope();
// Other registrations here
container = builder.Build();
这篇关于在静态类中访问或获取Autofac容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!