首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >避免依赖注入中的依赖周期

避免依赖注入中的依赖周期
EN

Stack Overflow用户
提问于 2017-12-18 15:42:13
回答 1查看 245关注 0票数 0

C#窗体应用程序。我有一个集线器和一个班。两者应该互相参照。这是因为:

  1. 从集线器,我需要调用类的方法
  2. 我需要从班里取回我的集线器

现在,我可以使用Autofac完成第一点:

代码语言:javascript
运行
复制
using Autofac;
using Autofac.Integration.SignalR;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Hosting;
using Owin;
using MyProject.Classes;
using System;
using System.Reflection;
using System.Windows.Forms;

namespace MyProject
{
    static class Program
    {
        static IDisposable webApp;

        [STAThread]
        static void Main()
        {
            string url = "http://localhost:8080";
            webApp = WebApp.Start(url);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Engine());
        }
    }

    class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);

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

在这里集线器:

代码语言:javascript
运行
复制
using Microsoft.AspNet.SignalR;
using MyProject.Classes;
using System;
using System.Threading.Tasks;

namespace MyProject.Hubs
{
    public class LiveHub : Hub
    {
        private readonly Erp _erp;

        public LiveHub(Erp erp)
        {
            _erp = erp;
        }

        public override Task OnConnected()
        {
            _erp.someMethod();
            return base.OnConnected();
        }
    }
}

在这里Erp.cs:

代码语言:javascript
运行
复制
public class Erp
{
    public Erp()
    {
    }

    public void SomeMethod()
    {
        // do something
    }

    public void SomeOtherMethod()
    {
        // usually I do:
        var hub = GlobalHost.ConnectionManager.GetHubContext<LiveHub>();
        hub.Clients.All.foo();
    }
}

但是这里我读到:

OWIN集成中的一个常见错误是使用GlobalHost。在OWIN中,您可以从头开始创建配置。在使用OWIN集成时,不应该引用GlobalHost。微软在这里有关于这个和其他IoC集成关注点的文档。

如果我不能使用“旧”方法,我应该如何检索我的集线器?我试图在Erp中为LiveHub添加另一个DI,但它不起作用。我以我的形式创建了一个Erp实例:

代码语言:javascript
运行
复制
public partial class Engine : Form
{
    private Erp _erp = new Erp();

    public Engine()
    {
        InitializeComponent();
    }
}

如果我添加DI声明将是不可能的,因为我需要在构造函数中定义LiveHub,这需要它本身的Erp参数.

我没看到什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-18 15:57:12

您可以通过发出事件将Hub与对象(在您的示例中为Erp)分离。

代码语言:javascript
运行
复制
namespace MyProject.Hubs
{
    public class LiveHub : Hub
    {    
        public event Action SomethingHappened;

        public override Task OnConnected()
        {
            SomethingHappened?.Invoke();
            return base.OnConnected();
        }
    }
}

现在,您可以连接Erp,而不必知道集线器。您必须在代码中的其他地方订阅该事件。但是循环引用被打破了。

要将引擎与Form分离,您可以这样做:

代码语言:javascript
运行
复制
public partial class EngineForm : Form
{    
    public EngineForm()
    {
        InitializeComponent();
    }
}

public class Engine
{
    public Engine(EngineForm form, Erp erp)
    {
        this.form = form;
        this.erp = erp;
    }

    // Here is where you'll write some code to coordinate
    // communication between the Erp and the EngineForm. 
    //
    // The main advantage is that you can inject the Erp 
    // and have it preconfigured.
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47871777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档