检索Autofac容器以解析服务

时间:2018-01-11 21:22:22

标签: c# owin autofac

在C#WindowForms应用程序中,我启动了一个OWIN WebApp,它创建了我的另一个类Erp的单例实例:

public partial class Engine : Form
{
    const string url = "http://*:8080"; //49396
    private IDisposable webApp;

    public Engine()
    {
        InitializeComponent();
        StartServer();
    }

    private void StartServer()
    {
        webApp = WebApp.Start<Startup>(url);
        Debug.WriteLine("Server started at " + url);
    }

    private void btnDoSomething(object sender, System.EventArgs e)
    {
       // needs to call a method in erp
    }
}

class Startup
{
    public void Configuration(IAppBuilder app)
    {
        Trace.Listeners.Remove("HostingTraceListener");
        app.UseCors(CorsOptions.AllowAll);

        var builder = new ContainerBuilder();
        var config = new HubConfiguration();
        builder.RegisterHubs(Assembly.GetExecutingAssembly()).PropertiesAutowired();
        var erp = new Erp();
        builder.RegisterInstance<Erp>(erp).SingleInstance();
        var container = builder.Build();
        config.Resolver = new AutofacDependencyResolver(container);
        app.UseAutofacMiddleware(container);
        app.MapSignalR(config);
    }
}

在创建WebApp之后,我想在我的代码的其他部分(即上面的按钮的事件处理程序)中检索单个erp实例。

据我了解,我需要使用resolve函数:

var erp = container.Resolve<Erp>();

但我不清楚如何在配置功能之外检索container

2 个答案:

答案 0 :(得分:2)

我不会过度思考它。在某处设置一个静态变量,然后抓住它。

public static class ContainerProvider
{
  public static IContainer Container { get; set; }
}

并在Startup中的块中:

var container = builder.Build();
ContainerProvider.Container = container;
config.Resolver = new AutofacDependencyResolver(container);

现在,您可以随时随地获取容器。

答案 1 :(得分:0)

编辑:我刚刚意识到接受的答案是Autofac项目的共同所有者,这让我感到困惑,因为它似乎违背了文档中的内容。我现在要留下答案,希望澄清。

只是想提供我自己的答案是因为虽然接受的答案会起作用;它通常被认为是不好的做法。

来自Autofac文档中的Best Practices and Recommendations部分:

  

使用关系类型,而不是服务定位器

     

为组件提供对容器的访问权限,将其存储在公共静态属性中,或者在全局“IoC”类上使用Resolve()等功能会失败使用依赖项注入的目的。这种设计与服务定位器模式有更多共同之处。

     

如果组件依赖于容器(或生命周期范围),请查看它们如何使用容器检索服务,并将这些服务添加到组件(依赖注入)构造函数参数中。

     

为需要实例化其他组件或以更高级方式与容器交互的组件使用关系类型。

您还没有给出如何在代码中使用它的具体方案,因此我无法为您提供准确的解决方案,但您是否有任何理由需要自己解决该实例?你能不能通过依赖注入传递Erp实例?

如果答案是肯定的,我在Autofac文档中Windows Forms Integration Guide页面改编的以下代码演示了如何做到这一点:

public partial class Form1 : Form {

    private readonly Erp _erp;

    public Form1(Erp erp) {
        this._erp = erp;

        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
        //do stuff with erp here
    }
}

然后,假设注册已正确设置,Autofac应将实例注入该类。

我希望这有帮助!