在Windsor中根据请求者的参数名称注册组件 [英] Register component based on parameter name on requestor in windsor
问题描述
我有使用AutoMapper的界面:
I have this interface for using AutoMapper:
public interface IMapper
{
object Map(object source, Type sourceType, Type destinationType);
}
然后对于每种类型的数据,我都有一个不同的mapper类,例如:
Then for each type of data, I have a different mapper class , for example:
public class UserMapper : IMapper
{
static UserMapper()
{
Mapper.CreateMap<User, UserViewModel>();
Mapper.CreateMap<UserViewModel, User>();
}
public object Map(object source, Type sourceType, Type destinationType)
{
return Mapper.Map(source, sourceType, destinationType);
}
}
然后,我将IMapper作为我的参数之一像这样的控制器类:
Then I have IMapper as one of the parametter in my controller class like this:
public UsersController(IUsersRepository repo, IMapper userMapper)
{....}
我正在将Windsor用作应用程序的IOC,问题是我要注册组件,以便在UsersController中运行时,使用UserMapper类;在ProductsController上运行时,它将使用我的ProductMapper类。
I am using Windsor as the IOC for my application and the problem is that I want to register the components, so that when running in UsersController , it use the UserMapper class and if running on ProductsController it will use my ProductMapper class.
我的注册代码与此类似:
My registration code looks something along the line of this:
container.Register(
Component.For<IMapper>()
.ImplementedBy<UsersMapper>()
.Named("usersMapper"),
Component.For<IMapper>()
.ImplementedBy<ProductsMapper>()
.Named("productsMapper"),
Component.For<ProductController>()
.ServiceOverrides(ServiceOverride.ForKey("usersMapper").Eq("productsMapper"))
)
我已经在Google和stackoverflow上完成了功课,并且我知道我需要使用ServicesOverride,但我仍然坚持这样做,有人可以帮我吗?
I have done my homework on google and stackoverflow, and i know that I need to use ServicesOverride but I am still stuck on this, could anyone give me a hand please?
谢谢
推荐答案
尽管svick的解决方案对我来说是正确的(尽管我没有尝试编译它),但这种情况是转化的绝佳案例基于ention的配置。
While svick's solution looks correct to me (I haven't attempted to compile it, though), this scenario is an excellent case for convention-based configuration.
我们引入以下约定: IMapper的每个使用者都将通过其名称来表示映射器的预期作用。默认情况下,该名称将与相同名称的类型匹配-仅使用不同的大小写。
因此,构造函数参数可以这样映射:
So, constructor parameters could be mapped like this:
- userMapper-> UserMapper
- productMapper-> ProductMapper
在温莎城堡中,这样的配置可能看起来像这样:
In Castle Windsor, such a configuration might look like this:
container.Register(Classes
.FromThisAssembly()
.Pick()
.WithServiceAllInterfaces()
.WithServiceSelf());
container.Kernel.Resolver.AddSubResolver(
new MapperConvention(container.Kernel));
Sub Resolver(真正发生魔术的地方)看起来像这样:
And the Sub Resolver (where the magic really happens) looks like this:
public class MapperConvention : ISubDependencyResolver
{
private readonly IKernel kernel;
public MapperConvention(IKernel kernel)
{
this.kernel = kernel;
}
public bool CanResolve(CreationContext context,
ISubDependencyResolver contextHandlerResolver,
ComponentModel model,
DependencyModel dependency)
{
return typeof(IMapper).IsAssignableFrom(dependency.TargetType);
}
public object Resolve(CreationContext context,
ISubDependencyResolver contextHandlerResolver,
ComponentModel model,
DependencyModel dependency)
{
var representativeMapperType = typeof(UserMapper);
var concreteMapperType = representativeMapperType.Assembly
.GetExportedTypes()
.Where(t =>
t.Name.Equals(dependency.DependencyKey,
StringComparison.OrdinalIgnoreCase))
.Single();
return this.kernel.Resolve(concreteMapperType);
}
}
这篇关于在Windsor中根据请求者的参数名称注册组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!