2010-01-14 84 views
3

我正在以編程方式註冊一組所有實現相同界面的服務,IRule。我還有一個服務,它看起來像這樣:如何以編程方式向Castle Windsor註冊依賴於已註冊組件列表的組件?

public class MyService { 
    private IEnumerable<IRule> _rules; 
    public MyService(IEnumerable<IRule> rules){ 
     _rules = rules; 
    } 
} 

哈米特發佈的東西,看起來像我想要的東西,http://hammett.castleproject.org/?p=257。我將簽名更改爲IRule [],並嘗試了帖子中的ArrayResolver技巧,但這對我沒有幫助(請注意,它也沒有破壞任何內容)。

任何人都知道如何以編程方式註冊一個組件,就像我上面發佈的代碼?

+0

從昨天看到這個職位由邁克:http://mikehadlow.blogspot.com/2008/09 /resolving-arrays-with-windsor.html – 2010-01-15 08:27:19

回答

2

我加載了Castle.MicroKernel的源代碼,並注意到已經有一個ArrayResolver和ListResolver(在Castle.MicroKernel.Resolvers.SpecializedResolvers命名空間中)。我從Hammet的博客上覆制的代碼無效,很可能是因爲自從編寫這個框架後框架發生了變化。

下面是一個示例項目演示如何做到這一點:http://www.panteravb.com/downloads/WindsorCon.zip

我試用過ArrayResolver和ListResolver,他們都工作順利,這是非常簡單的,所以假設這個服務類:

public class MyService 
{ 
    private IEnumerable<IRule> _rules; 
    public MyService(IList<IRule> rules) 
    { 
     _rules = rules; 
    } 
} 

你可以註冊這個傢伙是這樣的:

private IWindsorContainer _container; 
private void InitializeIoc() 
{ 
    _container = new WindsorContainer(); 
    _container.Kernel.Resolver.AddSubResolver(new ListResolver(_container.Kernel)); 
    _container.Register(Component.For<IRule>().ImplementedBy<Rule1>()); 
    _container.Register(Component.For<IRule>().ImplementedBy<Rule2>()); 
    _container.Register(Component.For<MyService>()); 
} 
+0

這不是爲我工作 – Miral 2011-03-07 13:34:53

+0

它確實工作,我使用列表,而不是IList Miral 2011-03-07 15:09:45

+0

偉大的答案克里斯。謝謝。提交了一個編輯以使其更清晰。我認爲這應該是最好的答案。 – 2011-10-02 02:42:32

6

如果你不想改變的MyService的簽名,並保持使用IEnumerable<IRule>,你也可以創建一個自定義的ISubDependencyResolver。這就是我們所做的:

public class EnumerableResolver : ISubDependencyResolver 
{ 
    private readonly IKernel kernel; 

    public EnumerableResolver(IKernel kernel) 
    { 
     this.kernel = kernel; 
    } 

    public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) 
    { 
     Type targetType = dependency.TargetType; 
     if (targetType == null) 
     { 
      throw new ArgumentException("TargetType property cannot be null", "dependency"); 
     } 

     if (targetType.IsGenericType && (targetType.GetGenericTypeDefinition() == typeof(IEnumerable<>))) 
     { 
      Type service = targetType.GetGenericArguments()[0]; 
      return this.kernel.HasComponent(service); 
     } 
     return false; 
    } 

    public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) 
    { 
     Type service = dependency.TargetType.GetGenericArguments()[0]; 
     Array array = this.kernel.ResolveAll(service, (IDictionary)null); 
     return Activator.CreateInstance(typeof(List<>).MakeGenericType(new Type[] { service }), new object[] { array }); 
    } 
} 

它需要像這樣的集裝箱進行註冊:

container.Kernel.Resolver.AddSubResolver(new EnumerableResolver(this.Kernel)); 
相關問題