在静态类中访问或获取Autofac容器 [英] Access or get Autofac Container inside a static class

查看:530
本文介绍了在静态类中访问或获取Autofac容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在静态类中获取或访问我的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆