2010-03-03 55 views

回答

6

是的,這是可能的。默認組件激活器僅用於公共構造函數。 您可以提供該組件,將採取內部構造考慮,或使用例如工廠,以激活組件定製組件激活:

var container = new WindsorContainer() 
    .AddFacility<FactorySupportFacility>() 
    .Register(Component.For<Foo>() 
        .UsingFactoryMethod(() => new Foo())); 
var foo = container.Resolve<Foo>(); 

但是你真的應該重新考慮使.ctor放在首位內部。這樣做確實不是一個好主意,特別是當你將課程作爲外部世界的組件暴露出來時。

+1

嗨Krzystzof,我認爲「如果它是如何完成的?」這個問題是隱含的!我猜不是。所以: 你怎麼做到的? 乾杯 Joni – joniba 2010-03-03 13:20:15

+0

謝謝伊恩。所以實際上我必須創建一個工廠來使用反射來構建這些組件。因爲Castle Windsor已經在使用反射來進行組件註冊,所以感到羞恥。但我理解這個推理。 再次感謝。 – joniba 2010-03-03 14:11:51

+1

+1表示重新考慮設計 – 2010-03-03 15:18:45

0

按照接受的答案的建議下,我才得以延長DefaultComponentActivatorprotected建設者的工作(它仍然無法與privateinternal工作;下面的代碼工作正常,那就是,但在別的東西DynamicProxy創建鏈失敗)。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 
using Castle.Core; 
using Castle.MicroKernel; 
using Castle.MicroKernel.ComponentActivator; 
using Castle.MicroKernel.Context; 

namespace /* YourNameSpaceHere */ 
{ 
    [Serializable] 
    public class NonPublicComponentActivator : DefaultComponentActivator 
    { 
     public NonPublicComponentActivator(ComponentModel model, IKernelInternal kernel, ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction) 
      : base(model, kernel, onCreation, onDestruction) 
     { /* do nothing */ } 

     private readonly List<Type> loadedTypes = new List<Type>(); 
     protected override ConstructorCandidate SelectEligibleConstructor(CreationContext context) 
     { 
      lock (loadedTypes) 
      { 
       if (!loadedTypes.Contains(context.RequestedType)) 
       { 
        loadedTypes.Add(context.RequestedType); 

        // Add the missing non-public constructors too: 
        var ctors = context.RequestedType.GetConstructors 
        (
         BindingFlags.NonPublic | BindingFlags.Instance 
        ); 

        foreach (var ctor in ctors) 
        { 
         Model.AddConstructor 
         (
          new ConstructorCandidate 
          (
           ctor, 
           ctor.GetParameters().Select(pi => new ConstructorDependencyModel(pi)).ToArray() 
          ) 
         ); 
        } 
       } 
      } 

      return base.SelectEligibleConstructor(context); 
     } 
    } 
} 

然後,您的容器上,你通過通用Activator方法針對ComponentRegistration對象登記本,所以我container.Register調用看起來是這樣的:

_container.Register 
    (
     // . . . 

     AllClasses.FromThisAssembly().BasedOn<ISomeInterface>() 
      .Configure 
      (
       c => c.LifeStyle.Transient 
        .Interceptors<MyInterceptor>() 
        .Activator<NonPublicComponentActivator>() // <--- REGISTERED HERE 
      ), 

     // . . . 
    ); 

希望幫助別人!