2017-12-18 20 views
0

C#Windowsフォームアプリケーション。 私はハブとクラスを持っています。どちらもお互いを参照する必要があります。 。これは:依存性注入の依存サイクルを避ける

  1. 私は今、私が最初に行うことができるよ、私のハブ

を取得する必要がクラスからクラスのメソッド

  • を呼び出す必要がハブから

    ここ
    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); 
         } 
        } 
    } 
    

    ハブ:

    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(); 
         } 
        } 
    } 
    
    Autofacを使用してポイント

    、ここErp.cs:

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

    けどhere私が読んで:

    をOWIN統合における一般的なエラーがGlobalHostの使用です。 OWINでは、最初から設定を作成します。 OWIN統合を使用している場合は、GlobalHostを参照するべきではありません。マイクロソフトでは、このIoCと他のIoCの統合に関する懸念事項について、ここにドキュメントを掲載

    「古い」方法を使用できない場合は、ハブをどのように取得する必要がありますか? 私はLiveHubのErpに別のDIを追加しようとしましたが、動作しません。私のフォームでは、私は、ERPのインスタンスを作成します。

    public partial class Engine : Form 
    { 
        private Erp _erp = new Erp(); 
    
        public Engine() 
        { 
         InitializeComponent(); 
        } 
    } 
    

    私はDIは、私はコンストラクタでLiveHubを定義する必要があるため、宣言ができなくなります、それはのERPパラメータ自体が必要であることを追加した場合...

    私は何を見ていないのですか?

  • +1

    だからあなたの 'LiveHub'がLiveHubに' Erp'とERPに依存して、それからである:

    は、あなたがこのような何かを行うことができFormからエンジンを切り離すために?それぞれの生涯は何ですか?それは通常避けることができる、すなわち設計上の問題である。そのようにする必要がある場合は、.ctorパラメータ(DI-ed)を取得し、もう1つは注入されたプロパティを取得します。 'PropertiesAutowired'を使わずに(そしてDIを通して.ctorだけ)、もう一つはプロパティー注入を使うために、通常は1つを設定する必要があります。 – NSGaga

    +0

    ...そして、追加するには、通常、コンストラクタに注入されるシングルトンである一方で、他のものがそのシングルトンにプロパティとして注入されるのが遅れているので、ライフタイムは重要です。 – NSGaga

    +0

    I/Oデバイスからデータを送受信するため、シングルトン(またはライフタイムスコープ)として 'Erp'が必要です。次に、クライアントが接続すると、クライアントからデータを送受信する必要があります。 'Erp'からクライアントのメソッドを呼び出すためだけにハブが必要です。 'LiveHub'からは、クライアントが要求したときにそのメソッドを呼び出すためだけに' Erp'が必要です。これを避ける方法はありますか? – Mark

    答えて

    2

    イベントを放出することにより、Hubのオブジェクト(あなたの場合はErp)からデカップリングすることができます。

    namespace MyProject.Hubs 
    { 
        public class LiveHub : Hub 
        {  
         public event Action SomethingHappened; 
    
         public override Task OnConnected() 
         { 
          SomethingHappened?.Invoke(); 
          return base.OnConnected(); 
         } 
        } 
    } 
    

    ここで、Erpをハブに知らせなくても接続できます。あなたはコード内の他の場所にイベントを購読する必要があります。しかし、循環参照は壊れています。

    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. 
    } 
    
    +0

    しかし、 'Erp'から、私はまだハブの*現在のインスタンスを取得する必要があります。私が新しいものを作成すると、もちろんイベントは捕捉されません。そして、ハブはクライアント – Mark

    +0

    ハブを 'Erp'クラスに注入できますか?そこからイベントを購読しますか? –

    +0

    ' Engine'クラスが 'Form'を拡張していることがわかります。 'Form'と' Erp'を注入する必要がある 'Engine'を作ることができれば助けになるでしょう –