我有问题让aufotac注入我的autopmapper typeconverters。我尝试了一些不同的方法,但我目前使用下面的代码。最接近寻求解决方案的是下面的代码(借用http://thoai-nguyen.blogspot.se/2011/10/autofac-automapper-custom-converter-di.html中的小位)。他的样本似乎以1:1的方式工作,但还没能找到我失踪的东西。像往常一样提取相关位,让我知道它是否不足。
我的autofac bootstrapper:
public class AutoFacInitializer
{
public static void Initialize()
{
//Mvc
var MvcContainer = BuildMvcContainer();
DependencyResolver.SetResolver(new AutofacDependencyResolver(MvcContainer));
//Web API
var ApiContainer = BuildApiContainer();
var ApiResolver = new AutofacWebApiDependencyResolver(ApiContainer);
GlobalConfiguration.Configuration.DependencyResolver = ApiResolver;
}
private static IContainer BuildApiContainer()
{
var builder = new ContainerBuilder();
var assembly = Assembly.GetExecutingAssembly();
builder.RegisterApiControllers(assembly);
return BuildSharedDependencies(builder, assembly);
}
private static IContainer BuildMvcContainer()
{
var builder = new ContainerBuilder();
var assembly = typeof (MvcApplication).Assembly;
builder.RegisterControllers(assembly);
builder.RegisterFilterProvider();
return BuildSharedDependencies(builder, assembly);
}
private static IContainer BuildSharedDependencies(ContainerBuilder builder, Assembly assembly)
{
//----Build and return container----
IContainer container = null;
//Automapper
builder.RegisterAssemblyTypes(assembly).AsClosedTypesOf(typeof(ITypeConverter<,>)).AsSelf();
AutoMapperInitializer.Initialize(container);
builder.RegisterAssemblyTypes(assembly).Where(t => typeof(IStartable).IsAssignableFrom(t)).As<IStartable>().SingleInstance();
//Modules
builder.RegisterModule(new AutofacWebTypesModule());
builder.RegisterModule(new NLogLoggerAutofacModule());
//Automapper dependencies
builder.Register(x => Mapper.Engine).As<IMappingEngine>().SingleInstance();
//Services, repos etc
builder.RegisterGeneric(typeof(SqlRepository<>)).As(typeof(IRepository<>)).InstancePerDependency();
container = builder.Build();
return container;
}
}
My Automap bootstrapper / initializer:
namespace Supportweb.Web.App_Start
{
public class AutoMapperInitializer
{
public static void Initialize(IContainer container)
{
Mapper.Initialize(map =>
{
map.CreateMap<long?, EntityToConvertTo>().ConvertUsing<LongToEntity<NavigationFolder>>();
map.ConstructServicesUsing(t => container.Resolve(t));
});
Mapper.AssertConfigurationIsValid();
}
}
}
我试图开始工作的转换器:
public class LongToEntity<T> : ITypeConverter<long?, T>
{
private readonly IRepository<T> _repo;
public LongToEntity(IRepository<T> repo)
{
_repo = repo;
}
public T Convert(ResolutionContext context)
{
long id = 0;
if (context.SourceValue != null)
id = (long)context.SourceValue;
return _repo.Get(id);
}
}
除转换器外,所有映射都能正常工作。该错误似乎表明我缺少ioc参考但我已经尝试但提到的ITypeConverter&lt;,&gt;和LongToEntity&lt;&gt;并没有看到帮助的变化。
答案 0 :(得分:6)
您当前的代码有三个问题:
您需要在注册任何映射之前致电ConstructServicesUsing
,如链接文章中所述:
棘手的是我们需要在注册mapper类之前调用该方法。
所以正确的Mapper.Initialize
如下:
Mapper.Initialize(map =>
{
map.ConstructServicesUsing(t => container.Resolve(t));
map.CreateMap<long?, EntityToConvertTo>()
.ConvertUsing<LongToEntity<NavigationFolder>>();
});
由于您的LongToEntity<T>
是开放式通用,因此您无法使用AsClosedTypesOf
,但您还需要使用RegisterGeneric
进行注册:
因此请更改您的ITypeConverter<,>
注册:
builder.RegisterAssemblyTypes(assembly)
.AsClosedTypesOf(typeof(ITypeConverter<,>)).AsSelf();
使用RegisterGeneric
方法:
builder.RegisterGeneric(typeof(LongToEntity<>)).AsSelf();
因为您已将Automapper初始化移动到单独的方法AutoMapperInitializer.Initialize
中,所以您无法使用文章中的clojure技巧,因此您需要在创建之后将其称为容器:
container = builder.Build();
AutoMapperInitializer.Initialize(container);
return container;