繁体   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