2017-12-18 21 views
0

C# Windows Form 응용 프로그램. 허브와 수업이 있습니다. 둘 다 서로를 참조해야합니다. 나는 지금 내가 처음을 할 수있어 내 허브 종속성 주입에서 종속성주기 피하기

를 검색하는 데 필요한 클래스에서

  • 를 '클래스를 호출 방법에 필요한 허브에서

    1. : 때문에 이입니다 Autofac 사용하여 포인트 :

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

      여기 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를 참조하면 안됩니다. Microsoft는 여기 및 기타 IoC 통합 문제에 대한 문서를 제공합니다.

      "이전"방법을 사용할 수없는 경우 어떻게 허브를 검색해야합니까? LiveHub 용 Erp에 다른 DI를 추가하려고했지만 작동하지 않습니다. 내 양식에서 나는 ERP의 인스턴스를 만들 :

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

      내가 생성자에서 LiveHub를 정의 할 필요가 있기 때문에 DI는 선언이 불가능할 것이라는 점을 추가하는 경우는, 그 자체의 ERP 매개 변수를 요구를 ...

      나는 무엇을 보지 못하니?

  • +1

    그래서'LiveHub'가 LiveHub에'Erp' 및 ERP에 따라, 그것은 것입니다 :

    당신이 이런 일을 할 수 Form에서 엔진을 분리하는 방법? 각각의 수명은 무엇입니까? 이는 보통 피할 수 있습니다 (예 : 디자인 문제). 그런 식으로 갈 필요가 있다면 .ctor 매개 변수 (DI-ed)를 취하고 또 다른 매개 변수는 주입 된 속성을 얻습니다. 일반적으로 'PropertiesAutowired'가없고 (DI 만 .ctor), 속성 주입을 사용하려면 하나를 설정해야합니다. – NSGaga

    +0

    ... 그리고 덧붙이면, 수명은 생성자에게 주입되는 싱글 톤이며, 다른 하나는 싱글 톤으로 속성으로 주입되기 때문에 일반적으로 중요합니다. – NSGaga

    +0

    I/O 장치로부터 데이터를 수신하고 보내기 때문에 'Erp'가 싱글 톤 (또는 평생 범위를 말함)으로 필요합니다. 그런 다음 클라이언트가 연결되면 해당 클라이언트와 데이터를 송수신해야합니다. 'Erp'에서 클라이언트의 메서드를 호출하기 위해서만 허브가 필요합니다. 'LiveHub'에서 클라이언트가 요청할 때'Erp' 메소드 만 호출하면됩니다. 이것을 피할 수있는 방법이 있습니까? – Mark

    답변

    2

    이벤트를 발생시켜 객체 (Erp 경우)에서 Hub을 분리 할 수 ​​있습니다.

    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

    Ok's Form'을 확장하는'Engine' 클래스가 있음을 볼 수 있습니다. 이렇게하면'Erp' 클래스를 삽입 할 수 없게됩니다. '폼과'Erp'가 주입되어야하는'Engine'을 만들 수 있다면 도움이 될 것입니다. –