[英]Access or get Autofac Container inside a static class
I need to get or access to my IoC container in a static class. 我需要在静态类中获取或访问我的IoC容器。 This is my (simplified) scenario:
这是我的(简化)场景:
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) 我在一个Startup类中注册ASP .net Web Api的依赖项(但我也是为MVC或WCF注册的。我有一个DependecyResolver项目,但为了简单起见,请考虑以下代码)
// 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? 知道我怎么能得到这个?
I need to get or access to my IoC container in a static class.
我需要在静态类中获取或访问我的IoC容器。 Any idea how can I get this?
知道我怎么能得到这个?
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. 具有静态
DomainEvents
类的模式源自Udi Dahan,但即使是Udi也承认这是一个糟糕的设计。 Static classes that require dependencies of their own are extremely painful to work with. 需要自己依赖的静态类非常难以使用。 They make the system hard to test and maintain.
它们使系统难以测试和维护。
Instead, create a IDomainEvents
abstraction and inject an implementation of that abstraction into classes that require publishing events. 相反,创建一个
IDomainEvents
抽象,并将该抽象的实现注入需要发布事件的类中。 This completely solves the your problem. 这完全解决了您的问题。
You can define your DomainEvents
class as follows: 您可以按如下方式定义
DomainEvents
类:
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();
You can create a static method inside your DomainEvents
class to inject the container like this: 您可以在
DomainEvents
类中创建一个静态方法来注入容器,如下所示:
public static class DomainEvents
{
public static void SetContainer(IContainer container)
{
Container = container;
}
....
}
And then from your ASP.NET application, call this method to inject the container: 然后从ASP.NET应用程序中调用此方法来注入容器:
DomainEvents.SetContainer(container);
Please note that I am giving you a direct answer to your question. 请注意,我将直接回答您的问题。 However, here are some issues that I see with this:
但是,我在这里看到了一些问题:
Only applications should have Composition Roots.
只有应用程序应具有组合根。 Libraries and frameworks shouldn't.
图书馆和框架不应该。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.