Access or get Autofac Container inside a static class

雨燕双飞 提交于 2019-12-04 07:13:24

I need to get or access to my IoC container in a static class. 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. 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. This completely solves the your problem.

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();

You can create a static method inside your DomainEvents class to inject the container like this:

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:

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:

  • Static classes should not be used when the class requires dependencies. In such case, refactor to use a non-static class and use Constructor Injection to inject the dependencies that you need in the class.
  • Using the container outside of the Composition Root is called Service Location and is considered an anti-pattern.
  • Class libraries should not use the container or even have a Composition Root. Quoting from the Composition Root article that I referenced:

Only applications should have Composition Roots. Libraries and frameworks shouldn't.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!