2016-09-18 1 views
2

내 자체에 대한 사용자 지정 시스템을 devlop하고 싶습니다.여러 동적 서비스 및 종속성 서비스로드에 대한 우수 사례

나는 종속성 서비스와 configuratin에 의해 사용자 정의 서비스를로드하려는 - 예를 들면 :

<Services> 
    <Service name="ServiceA" args="" type="CommonLib.IServiceA" dependencies=""/> 
    <Service name="ServiceB" args="" type="CommonLib.IServiceB" dependencies="ServiceA"/> 
    <Service name="ServiceC" args="" type="CommonLib.IServiceC" dependencies="ServiceA,ServiceB"/> 
    <Service name="ServiceD" args="" type="CommonLib.IServiceD" dependencies="ServiceA,ServiceB,ServiceC"/> 
    <Service name="ServiceE" args="" type="CommonLib.IServiceE" dependencies="ServiceA,ServiceB,ServiceC,ServiceD"/> 
    <Service name="ServiceF" args="" type="CommonLib.IServiceF" dependencies="ServiceA,ServiceB,ServiceC,ServiceD,ServiceE"/> 
</Services> 

그 모든 서비스는 사용자 지정 인터페이스 구현과 같습니다

public interface IService 
{ 
    bool Start(); 
    bool Stop(); 
    bool IsReady {get;} 
} 

무엇 toghether 동적 서비스를로드하기위한 가장 좋은 방법 하지만 그 의존성에 달려 있습니까?

모든 서비스를 반복하고 종속성이로드되고 준비 될 때까지 연기 하시겠습니까?

튜토리얼이 있습니까?

+2

이있는 [종속성 그래프 (https://en.wikipedia.org/wiki/Dependency_graph) .. –

+0

또한 위상 정렬입니까? 좋은 생각! –

+0

예, 토폴로지 정렬 솔루션을 사용하면 올바른로드 순서를 알 수 있습니다. –

답변

0

편집 : 그래프를 사용하여 주어진 서비스의 종속성을 매핑하는 것이 가장 좋습니다. Dependency Injection 프레임 워크를 사용하여 예제를 작성했습니다. 자유롭게 사용하거나 직접 만들 수 있습니다.

종속성 삽입 도구 (Unity, Simple Injector, Autofac, 구조 맵, Ninject)를 사용하면 종속성을 직접 주입 할 수 있습니다. 당신이 ServiceB 인스턴스를 요청하면

var container = new UnityContainer(); 
container.RegisterType<IServiceA, ServiceA>(); 
container.RegisterType<IServiceB, ServiceB>(); 

것은, 그것에서 ServiceA를 주입합니다 : 여기에 유니티를 사용하는 예입니다

var serviceB = container.Resolve<IServiceB>(); 

유니티에 대한 자세한 정보 : 내가로부터 제안을 받고 후 https://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx

+0

감사합니다.하지만 서비스를 주입하는 방법은 제 질문이 아닙니다. 제 질문은 서비스 로딩을위한 최상의 방법이지만, 서비스가로드되기 전에 서비스가로드됩니다 .. –

+0

그냥 내 대답에 더 많은 정보를 넣어. 혼자서하고 싶다면 다음 샘플을 참고하십시오. http://adventuresdotnet.blogspot.co.nz/2009/09/creating-your-own-ioc-container-part-2.html –

0

Remus Rusanu.

내 솔루션은 다음과 같습니다

public interface ITopologicalSort 
    { 
     string Id { get; } 
     IList<ITopologicalSort> Dependencies { get; set; } 
    } 

위상 정렬 : 코드

public static Dictionary<int, IList<T>> TopologicalSort<T>(IEnumerable<T> source, Func<T, IEnumerable<T>> getDependenciesFunc) where T : class, ITopologicalSort 
     { 
      var groups = new Dictionary<string, int>(); 
      var sortedGroups = new Dictionary<int, IList<T>>(); 
      foreach (var item in source) 
      { 
       TopologicalSortInternal(item, getDependenciesFunc, sortedGroups, groups); 
      } 
      return sortedGroups; 
     } 

private static int TopologicalSortInternal<T>(T item, Func<T, IEnumerable<T>> getDependenciesFunc, Dictionary<int, IList<T>> sortedGroups, Dictionary<string, int> groups) where T : class, ITopologicalSort 
     { 
      int level; 
      if (!groups.TryGetValue(item.Id, out level)) 
      { 
       groups[item.Id] = level = INPROCESS; 
       var dependencies = getDependenciesFunc(item); 
       if (dependencies != null && dependencies.Count() > 0) 
       { 
        foreach (var dependency in dependencies) 
        { 
         var depLevel = TopologicalSortInternal(dependency, getDependenciesFunc, sortedGroups, groups); 
         level = Math.Max(level, depLevel); 
        } 
       } 
       groups[item.Id] = ++level; 
       IList<T> values; 
       if (!sortedGroups.TryGetValue(level, out values)) 
       { 
        values = new List<T>(); 
        sortedGroups.Add(level, values); 
       } 
       values.Add(item); 
      } 
      return level; 
     } 

을하고 무엇

다음

는 위상 종류의 인터페이스입니다? 그는 의존성별로 정렬됩니다. 그래서 예를 들어

:

<Services> 
    <Service name="ServiceA" args="" type="CommonLib.IServiceA" dependencies=""/> 
    <Service name="ServiceB1" args="" type="CommonLib.IServiceB1" dependencies="ServiceA"/> 
    <Service name="ServiceB2" args="" type="CommonLib.IServiceB2" dependencies="ServiceA"/> 
    <Service name="ServiceC1" args="" type="CommonLib.IServiceC1" dependencies="ServiceA,ServiceB1"/> 
    <Service name="ServiceC2" args="" type="CommonLib.IServiceC2" dependencies="ServiceA,ServiceB2"/> 
    <Service name="ServiceD" args="" type="CommonLib.IServiceD" dependencies="ServiceA,ServiceB2,ServiceC2"/> 
    <Service name="ServiceE" args="" type="CommonLib.IServiceE" dependencies="ServiceA,ServiceB2,ServiceC2,ServiceD"/> 
    <Service name="ServiceF" args="" type="CommonLib.IServiceF" dependencies="ServiceA,ServiceB1,ServiceC1,ServiceD,ServiceE"/> 
</Services> 

Level 0: ServiceA 
Level 1: ServiceB1, ServiceB2 
Level 2: ServiceC2, ServiceC2 
Level 3: ServiceD 
Level 4: ServiceE 
Level 5: ServiceF