簡體   English   中英

如何在溫莎城堡中向多個通用服務注冊多個通用組件?

[英]How can I register multiple generic components with multiple generic services in castle windsor?

我在.net 4.0(c#)中使用Castle Windsor 3.0,並且遇到以下情況:

namespace Root
{
    public interface IGenericService<T>
    {        
    }
    public class GenericService<T> : IGenericService<T>
    {        
    }
}    
namespace Root.A
{
    public class Something
    {        
    }
    //... Some other classes
}

我想要做的是在容器中為與“ Something”在相同命名空間中的每個類注冊IGenericService的實現。

我可以這樣做,但我想知道,是否可以使用Castle Windsor流利的配置API?

private static void RegisterComponents(IWindsorContainer container)
{            
    // Get all the types in the same namespace as "Something"
    // I.e AllTypes.FromThisAssembly().InSameNamespaceAs<Something>()
    var type = typeof(Something);
    var types = type
        .Assembly
        .GetTypes()
        .Where(t => t.Namespace != null &&
                    t.Namespace.Equals(type.Namespace,
                                       StringComparison
                                           .InvariantCultureIgnoreCase));

    // For each of those types register a component GenericService<T>
    // with service IGenericService<T> where T is each type
    Type genericBaseType = typeof(GenericService<>);
    string assemblyName = genericBaseType.Assembly.GetName().FullName;
    string genericBaseName = genericBaseType.FullName;
    foreach (var t in types)
    {
        var ser = typeof(IGenericService<>);
        var serAssemblyName = ser.Assembly.GetName().FullName;
        string serviceFullName = string.Format(
               CultureInfo.InvariantCulture,
               "{0}[[{1}]], {2}",
               ser.FullName,
               t.AssemblyQualifiedName,
               serAssemblyName);
        var serviceType = Type.GetType(serviceFullName);


        string componentFullName = string.Format(
            CultureInfo.InvariantCulture,
            "{0}[[{1}]], {2}",
            genericBaseName,
            t.AssemblyQualifiedName,
            assemblyName);
        var componentType = Type.GetType(componentFullName);


        container.Register(Component
            .For(serviceType)
            .ImplementedBy(componentType)
            .LifestylePerWebRequest());
    }
}

經過很長時間的搜索,我認為答案是您做不到,問題中發布的代碼是實現此目標的唯一方法,是的,這是相當麻煩的事,並着眼於應用程序從整體上講,在大多數情況下可能會有更好的設計。

就像任何其他IoC容器一樣,Castle Windsor 在全局范圍內注冊類型,這意味着,如果您注冊說接口的實現,則它在整個應用程序中具有作用域。 您不能將其限制為名稱空間。

但是,對於這種情況,有一種解決方法,例如,您可以注冊一個命名組件。

container.Register(Component
    .For(serviceType)
    .Named("NamespaceA")     //<------HERE
    .ImplementedBy(componentType_NamespaceA) //one type
    .LifestylePerWebRequest());

container.Register(Component
    .For(serviceType)
    .Named("NamespaceB")     //<------HERE
    .ImplementedBy(componentType_NamespaceB)  //another type
    .LifestylePerWebRequest());

現在,您可以通過接口和名稱來解析所需的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM