使用ninject和通用接口的自动映射将不起作用(错误激活/没有匹配的绑定可用)

时间:2016-01-05 13:15:11

标签: c# generics ninject automapper

我正在尝试将automapper与ninject和通用接口(抽象类)结合使用。但它似乎没有用。

下面你会找到我正在尝试使用的代码。我错过了什么?

IMapper

mysqli_set_charset($conn,"utf8");

CategoryRepresentationMapper

 public interface IMapper<in TTypeFrom, TTypeTo>
{
    TTypeTo Map(TTypeFrom typeFrom);
    List<TTypeTo> Map(IEnumerable<TTypeFrom> itemToMap);
}
public abstract class Mapper<TTypeFrom, TTypeto> : IMapper<TTypeFrom, TTypeto>
{
    private readonly IMappingEngine _mappingEngine;
    private readonly IConfiguration _configuration;

    protected Mapper(IMappingEngine mappingEngine, IConfiguration configuration)
    {
        _mappingEngine = mappingEngine;
        _configuration = configuration;

        _configuration.CreateMap<TTypeFrom, TTypeto>();
    }

    public TTypeto Map(TTypeFrom typeFrom)
    {
        return Map<TTypeFrom, TTypeto>(typeFrom);
    }
    protected TTo Map<TFrom, TTo>(TFrom itemToMap)
    {
        return _mappingEngine.Map<TFrom, TTo>(itemToMap);
    }

    public List<TTypeto> Map(IEnumerable<TTypeFrom> itemToMap)
    {
        return Map<TTypeFrom, TTypeto>(itemToMap);
    }
    protected List<TTo> Map<TFrom, TTo>(IEnumerable<TFrom> itemsToMap)
    {
        return itemsToMap.Select(Map<TFrom, TTo>).ToList();
    }
}

使用ninject进行设置

public interface ICategoryRepresentationMapper : IMapper<CategoryRepresentation, CategoryRepresentationDto>
{

}
public class CategoryRepresentationMapper : Mapper<CategoryRepresentation, CategoryRepresentationDto>, ICategoryRepresentationMapper
{
    public CategoryRepresentationMapper(IMappingEngine mappingEngine, IConfiguration configuration) : base(mappingEngine, configuration)
    {
    }
}

我收到以下错误:

IKernel kernel = new StandardKernel();


        Mapper.Initialize(map =>
        {
            map.ConstructServicesUsing(f => kernel.Get(f));
        });

        kernel.Bind<IMappingEngine>().ToMethod(x => Mapper.Engine);
        kernel.Bind<IConfigurationProvider>().ToMethod(x => Mapper.Engine.ConfigurationProvider);
        kernel.Bind<IConfiguration>().ToMethod(x => Mapper.Configuration);

        kernel.Bind(
          x =>
              x.FromAssemblyContaining(typeof(IMapper<,>))
                  .SelectAllClasses()
                  .InheritedFrom(typeof(IMapper<,>))
                  .BindAllInterfaces());

        var categoryRepresentationMapper = kernel.Get<ICategoryRepresentationMapper>();

修改

如果我这样做,它会工作,但我不想明确绑定ICategoryRepresentationMapper。它必须是通用的,因为我将有许多映射器。

 Ninject.ActivationException occurred
  HResult=-2146233088
  Message=Error activating ICategoryRepresentationMapper
No matching bindings are available, and the type is not self-bindable.
Activation path:
  1) Request for ICategoryRepresentationMapper

Suggestions:
  1) Ensure that you have defined a binding for ICategoryRepresentationMapper.
  2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
  3) Ensure you have not accidentally created more than one kernel.
  4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
  5) If you are using automatic module loading, ensure the search path and filters are correct.

1 个答案:

答案 0 :(得分:0)

我似乎找到了这个问题的答案。集会要看错了。

而不是这样做:

kernel.Bind(
      x =>
          x.FromAssemblyContaining(typeof(IMapper<,>))
              .SelectAllClasses()
              .InheritedFrom(typeof(IMapper<,>))
              .BindAllInterfaces());

我需要这样做并且有效:

var codeBase = Assembly.GetExecutingAssembly().CodeBase;
        var uri = new UriBuilder(codeBase);
        var path = Uri.UnescapeDataString(uri.Path);

        _kernel.Bind(
          x =>
              x.FromAssembliesInPath(Path.GetDirectoryName(path))
                  .SelectAllClasses()
                  .InheritedFrom(typeof(IMapper<,>))
                  .BindAllInterfaces());