2014-07-23 17 views
7

Her zaman kesişmesi gereken birkaç yöntem içeren soyut bir temel sınıfım var. Temel sınıf, kullanıcı tanımlı sınıflar tarafından miras alınabilir ve uygulama başlangıcında kapsayıcıya kaydedilebilir. Kullanıcının bir kaydı olmadıysa, konteyner yükleyicisi bir kişinin kendisini kaydedecektir.Castle Windsor, bileşen zaten kaydedildikten sonra seçici ile ara uygulayıcılar uygular

İşte sorun - kullanıcı interceptoru ekleme konusunda endişelenmemeli. Konteyner, bileşeni kimin ve nerede kayıtlı olduğuna bakmaksızın, kendi başına eklemelidir.

Şu ana yapıyorum budur:

if(!container.Kernel.HasComponent(typeof(MyBaseComponent))) 
    container.Register(Component.For<MyComponent>() 
     .Interceptors(InterceptorReference 
     .ForType<MyComponentMethodInterceptor>()) 
     .SelectedWith(new MyComponentMethodSelector()).AtIndex(1)); 

MyComponentMethodSelector yontemadi ben (bu durumda bir MyComponentMethodInterceptor buna ekleniyor) yolunu kesmek gerekir birini eşit olup olmadığını denetler basit IInterceptorSelector olduğunu.

Gördüğünüz gibi, öğenin önceden kaydedilmiş olup olmadığını kontrol eder.

Sorun şu ki - zaten kayıtlı ise bir engelleyici ekleyebilir miyim? Akla gelen en belirgin seçim bir IContributeComponentModelConstruction kullanıyor, ancak o noktada engelleyicinin ekleneceği yöntemi seçemiyorum. Yoksa orada mı?

DÜZENLEME:

Ben biraz daha belirgin olması gerekirdi. Sadece belirli bir yöntem için bir engelleyici eklemem gerekiyor. Bu yüzden bir MyComponentMethodSelector kullanıyorum. IContributeComponentModel'in farkındayım ve bunun için bir yöntem seçicisi eklemenin bir yolu olmadığını anlayana kadar bununla başladım.

+0

neros: Bir tesis

public class InterceptionFacility : AbstractFacility { protected override void Init() { Kernel.ComponentRegistered += new Castle.MicroKernel.ComponentDataDelegate(Kernel_ComponentRegistration); } void Kernel_ComponentRegistration(string key, Castle.MicroKernel.IHandler handler) { if (typeof(IEventuallyRegistered).IsAssignableFrom(handler.ComponentModel.Implementation)) { handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(EventuallyRegisteredInterceptor))); } } } 

Sonra bileşenin önce konteynere için kayıt tesis ekleyebilir ya da bileşeni kaydederken sizin tesis olay özleyeceğim oluşturarak başlayacaktı İstediğin şeyi nasıl halledebileceğini bulmak için herhangi bir şansın var mıydı, bunu duymak isterdim – samy

+0

Ne yazık ki yok. Farklı bir projeye yeniden atandım, bu yüzden şu anda beklemede. Yine de bir noktaya geri döneceğim. – NeroS

cevap

8

IContributeComponentModelConstruction uygulayarak, hizmetinizin bileşen modelinin yapımında çağrılan bir ComponentModel yapı katkıcısı ile bir bileşene kolayca yapılandırma ekleyebilirsiniz.

Diyelim ki IEventuallyRegistered herhangi uygulanmasına bir önleme eklemek istediğinizi varsayalım, ve kullanıcının DefaultRegistration kullanmak istediğiniz özel bir bileşen kayıt olmasaydı: IContributeComponentModelConstruction arabirim uygulama

public interface IEventuallyRegistered { void test(); } 
public class DefaultRegistration : IEventuallyRegistered { public void test() { } } 
public class EventuallyRegisteredInterceptor : IInterceptor 
{ 
    public void Intercept(IInvocation invocation) { invocation.Proceed(); } 
} 

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     var container = new Castle.Windsor.WindsorContainer(); 
     container.Register(Component.For<EventuallyRegisteredInterceptor>()); 
     container.Register(Component.For<IEventuallyRegistered>().ImplementedBy<DefaultRegistration>()); 
     // I'm not doing the optional registration, I just want to 
     // demonstrate upgrading a additional configuration 

     var t = container.Resolve<IEventuallyRegistered>(); 
     t.test(); 
    } 
} 

değiştirmek sağlar bileşen modelinin konfigürasyonu oluşturulduğu zaman:

public class RequireInterception : IContributeComponentModelConstruction 
{ 
    public void ProcessModel(IKernel kernel, ComponentModel model) 
    { 
     if (model.Services.Contains(typeof(IEventuallyRegistered))) 
     { 
      model.Interceptors.Add(new InterceptorReference(typeof(EventuallyRegisteredInterceptor))); 
     } 
    } 
} 

Sonra registeri önce konteynere için bileşen eklemek Bileþeniniz ng: önerilmeyen bir tesis, ile çekirdeğin ComponentRegistered olay aracılığıyla yapmak mümkün olsa da

container.Kernel.ComponentModelBuilder.AddContributor(new RequireInterception()); 
container.Register(Component.For<IEventuallyRegistered>().ImplementedBy<DefaultRegistration>()); 

; orijinal cevaba dahil edildim çünkü ben dahil ediyorum ama aşağı itiyorum.,

container.AddFacility<InterceptionFacility>(); 
container.Register(Component.For<IEventuallyRegistered>().ImplementedBy<DefaultRegistration>()); 
+1

"IContributeComponentModelConstruction" çözümünü öneririm. Ben Bu hızlı bir göz üzerinde umut verici görünüyor –

+0

modifiye için bir anlamı yoktur, ben de denemek olacak ve eğer bunun için çalışıyorsa, kabul edilir olarak işaretleyeceğim :) – samy

+0

teyit için, teşekkürler Ben de öyle düşündüm 'ComponentModel' – samy

İlgili konular