2013-10-23 3 views
0

아래의 유닛 테스트에서 MyInterFace [] 배열의 두 개의 다른 그룹을 주입하려고합니다.하지만 잘못된 방법으로 처리하는 것처럼 보입니다. 인스턴스를 얻을 것이므로 오히려 비효율적이다 IMyInterface의 모든 내 구현, ....컬렉션의 다른 그룹을 해결

namespace UnitTest.Interface 
{ 
    public interface IMyInterface 
    { 

    } 
} 

namespace UnitTest.ArrayGroup1 
{ 
    public class MyInjected1 : IMyInterface 
    { 
     public static int Instancecount { get; set; } 
     public MyInjected1() 
     { 
      Instancecount++; 
     } 

    } 

    public class MyInjected2 : IMyInterface 
    { 
     public static int Instancecount { get; set; } 
     public MyInjected2() 
     { 
      Instancecount++; 
     } 
    } 
} 

namespace UnitTest.ArrayGroup2 
{ 
    public class MyInjected3 : IMyInterface 
    { 
     public static int Instancecount { get; set; } 
     public MyInjected3() 
     { 
      Instancecount++; 
     } 
    } 

    public class MyInjected4 : IMyInterface 
    { 
     public static int Instancecount { get; set; } 
     public MyInjected4() 
     { 
      Instancecount++; 
     } 
    } 
} 


namespace UnitTest 
{ 
    public class MyClass1 
    { 
     private IMyInterface[] collection; 
     public MyClass1(IMyInterface[] group1collection) 
     { 
      collection = group1collection; 
     } 
    } 

    public class MyClass2 
    { 
     private IMyInterface[] collection; 
     public MyClass2(IMyInterface[] group2collection) 
     { 
      collection = group2collection; 
     } 
    } 

    public class MySubResolver : ISubDependencyResolver 
    { 
     private readonly IKernel kernel; 
     public MySubResolver(IKernel kernel) 
     { 
      this.kernel = kernel; 
     } 
     public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) 
     { 
      return dependency.TargetType == typeof(IMyInterface[]); 
     } 

     public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) 
     { 
      IMyInterface[] res; 
      if (dependency.DependencyKey == "group1collection") 
       res= kernel.ResolveAll<IMyInterface>().Where(t => 
       { 
        var ns = t.GetType().Namespace; 
        return ns != null && ns.StartsWith("UnitTest.ArrayGroup1"); 
       }).ToArray(); 
      else 
       res= kernel.ResolveAll<IMyInterface>().Where(t => 
       { 
        var ns = t.GetType().Namespace; 
        return ns != null && ns.StartsWith("UnitTest.ArrayGroup2"); 
       }).ToArray(); 
      return res; 
     } 
    } 



    [TestClass] 
    public class UnitTest1 
    { 
     [TestMethod] 
     public void TestMethod1() 
     { 
      var kernel = new DefaultKernel(new DefaultProxyFactory()); 
      kernel.Resolver.AddSubResolver(new MySubResolver(kernel));  
      var container = new WindsorContainer(kernel, new DefaultComponentInstaller()); 
      container.Register(
       Classes.FromThisAssembly() 
         .BasedOn<IMyInterface>() 
         .WithServiceFirstInterface() 
         .LifestyleTransient()); 
      container.Register(Component.For<MyClass1>().LifeStyle.Transient); 
      container.Register(Component.For<MyClass2>().LifeStyle.Transient); 

      var sut=container.Resolve<MyClass1>(); 

      Assert.AreEqual(MyInjected1.Instancecount, 1); 
      Assert.AreEqual(MyInjected2.Instancecount, 1); 
      Assert.AreEqual(MyInjected3.Instancecount, 0); 
      Assert.AreEqual(MyInjected4.Instancecount, 0); 
     } 
    } 
} 

어떻게 ResolveAll 내 SubResolver에 전화 않기 때문에 나는 단지 내가 정말 필요로하는 클래스로 생성 된 인스턴스를 얻을의 생성 ??

TIA

/소렌 지금은 질문을 이해

답변

0

ResolveAll을 사용해야합니까? 만약 당신이 상관하지 않는다면, 이것은 트릭을 당신의 서브 - 리졸버의 Resolve 방법으로 할 것입니다.

public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) 
    { 
     IMyInterface[] res; 
     IHandler[] handlers; 

     if (dependency.DependencyKey == "group1collection") 
     { 
      handlers = kernel.GetHandlers(typeof(IMyInterface)).Where(handler => handler.ComponentModel.Implementation.Namespace.StartsWith("UnitTest.ArrayGroup1")).ToArray(); 
     } 
     else 
     { 
      handlers = kernel.GetHandlers(typeof(IMyInterface)).Where(handler => handler.ComponentModel.Implementation.Namespace.StartsWith("UnitTest.ArrayGroup2")).ToArray(); 
     } 

     res = new IMyInterface[handlers.Length]; 
     for (int i = 0; i < res.Length; i++) 
     { 
      res[i] = handlers[i].Resolve(context) as IMyInterface; 
     } 

     return res; 
    } 
+0

그게 .... 그것을 해결할 것이다 고마워 .... – smolesen

0

, 내가 분명히 도움이 될 수 있다면 나를 보자.

ResolveAll이 술어 인수를 취한 경우 성 사람들은 해상도를 필터링 할 수있는 지점에 있습니다. 그러나 System.Linq 확장을 사용하기 때문에 컬렉션이 생성 될 때까지 필터링 할 수 없으며성에 의해 해결됩니다.

New in castle version 3은 IHandlerFilter와 정확히 일치합니다.

+0

문제는 MyInjected3 & Myinjected4의 인스턴스가 난 단지 MyInjected1 & MyInjected2 필요에도 불구하고, 만들어지고 있다는 것입니다 ... 나는 경우가 (저가) 간단 해요,하지만 복잡한 경우는 수 필요하지 않은 객체를 인스턴스화하는 데 많은 비용이 듭니다. ResolveAll <>(). where()가 where 절을 충족하는 객체 만 인스턴스화 할 것으로 예상했을 것입니다. – smolesen

+0

나는 MyClass1만을 해결하므로, MyInjected3 및 MyInjected4의 인스턴스가 인스턴스화되는 것을 기대하지는 않는다 ... – smolesen

+0

IHandlersFilter가 어떻게 도움이 될지 확실하지 않다 ... IHandlersFilter는 내가 해결하려고하는 유형에 대해 알고있다. 가능한 핸들러이지만 DependencyModel (group1collection)에 대해 알지 못하는 것 같아서, 어떻게 든 ResolveAll에게 주어진 IHandlersFilter를 사용하지 않으면 문제가 실제로 해결되지 않습니다. – smolesen

관련 문제