2008-12-24 4 views
6

이 질문이 너무 구체적인지는 모르겠지만 가능하다면 Castle Windsor를 Unity에 사용하는 응용 프로그램을 포팅해야합니다. 이렇게하면 비 -Microsoft 승인 라이브러리에 의존하지 않게됩니다. 나는 내가 아는 것을 알지만 무엇을 할 것인가.Castle Windsor to Unity - CW에서와 같은 방법으로 Unity에서 자동 구성 할 수 있습니까?

어쨌든 나는 그것을 관리했지만 내가 가진 것에 만족하지 않습니다. 윈저에서 나는이 있었다 : 당신은 내가 매일 일을 등록하는 데 참조하기보다는 어떤 종류를 사용할 수 수 있듯이 나는 통일

RegisterType<IMainView, MainView>(); 
     RegisterType<IConfigureLinkView, ConfigureLinkView>(); 
     RegisterType<IConfigureSourceView, ConfigureSourceView>(); 
     RegisterType<IConfigureSinkView, ConfigureSinkView>(); 
     RegisterType<MainPresenter, MainPresenter>(); 
     RegisterType<ConfigureLinkPresenter, ConfigureLinkPresenter>(); 
     RegisterType<ConfigureSourcePresenter, ConfigureSourcePresenter>(); 
     RegisterType<ConfigureSinkPresenter, ConfigureSinkPresenter>(); 

이로 변환 한

Register(
      AllTypes.Of(typeof(AbstractPresenter<>)).FromAssemblyNamed("Links.Mvp"), 
      AllTypes.Of(typeof(IView)).FromAssemblyNamed("Links.WinForms").WithService.FromInterface()); 

자동 구성. 그래서 제 질문은 이렇습니다 : 화합으로이 일을하는 더 좋은 방법이 있습니까?

감사합니다.

아담.

+0

아이디어는 CastleWindsor의 소스에 등록()에 사용되는 코드를 추출하고, 유니티 용기의 해제 확장 방법을하는 것입니다. – eduncan911

+0

유니티로 이사하시는 분께는 위로를드립니다. 당신은 고통의 세계에 종사하고 있습니다. 특히 Windsor를 광범위하게 사용한다면, non-trivially 일 것입니다. –

답변

0

차갑다. 이 기능은 아직 통합되지 않았지만 조금 야심적이라면 컨벤션 기반 등록을 설정할 수 있습니다. 아래는 실행중인 어셈블리와 인터페이스에서 작동하는 snipped입니다. 행운을 빕니다.

P. 이것은 큰 해킹처럼 느껴질 것입니다. 아마도 모든 유형을 수동으로 등록하는 작업을 계속할 것입니다.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using System.Reflection; 

namespace Forum 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // get your assemblies and types you can register 
      Assembly a = Assembly.GetExecutingAssembly(); 
      var types = a.GetTypes();    
      var bindTo = from t in types 
         where t.IsAbstract || t.IsInterface 
         select t; 

      // apply your conventions to filter our types to be registered 
      var interfacePairs = from t in bindTo.Where(x => x.IsInterface) 
           let match = types.FirstOrDefault(x => x.Name ==  t.Name.Substring(1)) 
           where match != null 
           select new Pair { To = t, From = match }; 
      var abstractPairs = new Pair[] {}; 


      // setup the generic form of the method to register the types 
      var thisType = typeof(Program); 
      var bindings = BindingFlags.Static | BindingFlags.Public; 
      MethodInfo genericMethod = thisType.GetMethod("RegisterType", bindings);    

      // register all your types by executing the 
      // specialized generic form of the method 
      foreach (var t in interfacePairs.Concat(abstractPairs)) 
      { 
       Type[] genericArguments = new Type[] { t.To, t.From }; 
       MethodInfo method = genericMethod.MakeGenericMethod(genericArguments); 
       method.Invoke(null, new object [] {}); 
      } 

      Console.ReadKey(); 
     } 

     public static void RegisterType<To, From>() 
     { 
      Console.WriteLine("Register { To: {0} From: {1} }", typeof(To), typeof(From)); 
     } 

     // Test classes that should be picked up 
     interface ITest { } 
     class Test : ITest { } 

     class Pair 
     { 
      public Type To { get; set; } 
      public Type From { get; set; } 
     }   
    } 
} 
+1

CastleWindsor의 소스가 비슷한 것을합니다 (해가 더 우아합니다). 그에게 더 좋은 아이디어는 Register()에 사용 된 코드를 뽑아 내고 Unity 컨테이너에서 확장 메서드를 해제하는 것입니다/ – eduncan911

+0

Windsor에서 가져 와서 Unity에 적용한다는 것은 분명합니다. 왜 안돼! 예 ... 우아함? 어쩌면 다음 프로젝트;). – smaclell

-1

AFAIK 여기에는 Unity에서 할 수있는 방법이 없습니다. 통일성은 윈저보다 성숙하고 성숙한 용기가 아예 없으며, 그 결과로 많은 것들이 더 어렵거나 불가능합니다.

5

확인 this 아웃 : 난 그냥 윈저에 대한 규칙 기반의 등록에 관한 정보를 찾고이 질문을 우연히 발견하고 이것이 내가 생각 상당히 오래된 질문이있는 동안 나는 다른 사람에 대한 대답을 떠날 것

 var container = new UnityContainer(); 

     container 
      .ConfigureAutoRegistration() 
      .LoadAssemblyFrom("Plugin.dll") 
      .IncludeAllLoadedAssemblies() 
      .ExcludeSystemAssemblies() 
      .ExcludeAssemblies(a => a.GetName().FullName.Contains("Test")) 
      .Include(If.Implements<ILogger>, Then.Register().UsingPerCallMode()) 
      .Include(If.ImplementsITypeName, Then.Register().WithTypeName()) 
      .Include(If.Implements<ICustomerRepository>, Then.Register().WithName("Sample")) 
      .Include(If.Implements<IOrderRepository>, 
        Then.Register().AsSingleInterfaceOfType().UsingPerCallMode()) 
      .Include(If.DecoratedWith<LoggerAttribute>, 
        Then.Register() 
          .AsInterface<IDisposable>() 
          .WithTypeName() 
          .UsingLifetime<MyLifetimeManager>()) 
      .Exclude(t => t.Name.Contains("Trace")) 
      .ApplyAutoRegistration(); 
+0

뻔뻔한 자기 승진! 나는 그것을 좋아한다. – smaclell

+0

또한 아주 좋은 소스 코드. Unity를 사용해야한다면 반드시 포함 시키십시오;). – smaclell

0

사람 Unity에서 이러한 종류의 기능을 찾고 있을지도 모릅니다.

작년에 Unity에 대한 컨벤션 기반 등록 확장 프로그램을 작성했습니다.이 확장 프로그램은 here에 대해 읽을 수 있습니다. 실제 다운로드는 Google 코드 here에서 가능합니다. 기본적인 사용법은 다음과 같습니다

_container 
       .Using<IConventionExtension>() 
       .Configure(x => 
        { 
         x.Conventions.Add(new ClosingTypeConvention(typeof (IRepository<>))); 
         x.Assemblies.Add(Assembly.GetExecutingAssembly()); 
        }) 
       .Register(); 
2

유니티 3 지금 밖으로 상자의 규칙에 의해 등록을 지원

_container 
     .Using<IConventionExtension>() 
     .Configure(x => 
      { 
       x.Conventions.Add<InterfaceImplementionNameMatchConvention>(); 
       x.Assemblies.Add(Assembly.GetExecutingAssembly()); 
      }) 
     .Register(); 

또한 자동 등록 열려있는 일반적인 유형에 대한 ClosingTypeConvention 있습니다.

등록 및 컨벤션 다음과 인터페이스에 대한 모든 고정 구현지도 것 다음 IFoo를 -, 당신은 그대로 (콘크리트 타입 클래스를 등록 할 필요가 없습니다 그런데> 푸

var container = new UnityContainer(); 
container.RegisterTypes(
    AllClasses.FromLoadedAssemblies(), 
    WithMappings.MatchingInterface, 
    WithName.Default); 

을 XXXPresenter 클래스의 경우) 다른 유형으로 매핑되지 않으면 ... 클래스가 구체적인 유형에 의존하면 Unity가 자동으로 빌드합니다.

사용할 어셈블리 또는 형식을 필터링하거나 매핑을 수행하는 방법과 같은 규칙을 사용하여 더 많은 작업을 수행 할 수 있지만 다음과 같은 몇 가지 사항을 다루므로 MSDN의 예제를 참조하십시오.

http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx#sec23