I am using Castle Windsor 3.0 in .net 4.0 (c#) and I have the following situation:
namespace Root
{
public interface IGenericService<T>
{
}
public class GenericService<T> : IGenericService<T>
{
}
}
namespace Root.A
{
public class Something
{
}
//... Some other classes
}
What I want to do is have an implementation of IGenericService registered in the container for every class that is in the same namespace as "Something".
I can do it like this but I am wondering, is it possible using the Castle Windsor fluent configuration 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());
}
}
经过很长时间的搜索,我认为答案是您做不到,问题中发布的代码是实现此目标的唯一方法,是的,这是相当麻烦的事,并着眼于应用程序从整体上讲,在大多数情况下可能会有更好的设计。
As any other IoC container Castle Windsor registers types globally , which means if you register an implementation of say an interface, it has a scope for the whole application. You cannot limit it to a namespace.
However, there is a workaround for this situation, where you can register a named component, for example
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());
Now you can resolve the type that you need by the interface and name.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.