根据windsor请求者上的参数名称注册组件 [英] Register component based on parameter name on requestor in windsor

查看:25
本文介绍了根据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 的解决方案在我看来是正确的(虽然我没有尝试编译它),但这种情况对于 convention-based 来说是一个很好的例子配置.

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 的每个使用者都将通过其名称来表明映射器的预期角色.默认情况下,该名称将与同名类型匹配 - 只是大小写不同.

Let's introduce this convention: Each consumer of IMapper will signal the intended role of the mapper by its name. By default, that name will be matched with a type of the same name - only with different casing.

所以,构造函数的参数可以这样映射:

So, constructor parameters could be mapped like this:

  • 用户映射器 -> 用户映射器
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆