我有一个多租户Web应用程序,它有多个模块。我使用autofac作为IOC和Automapper来映射我的模型和实体。在下面的代码中,我能够将UserAuthenticationMapper配置文件添加到automapper,但无法添加CustomerDataMapper配置文件。 Autofac仅向自动化MappingEngine添加一个映射器配置文件,并忽略其余部分。 我在这做错了什么?
这是我的UserAuthentication模块:
public class UserAuthenticationModule: Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MappingEngine>().As<IMappingEngine>();
builder.Register(ctx =>
{
var configStore = new ConfigurationStore
(new TypeMapFactory(), MapperRegistry.AllMappers());
configStore.AddProfile<UserAuthenticationMapperProfile>();
return configStore;
})
.AsImplementedInterfaces()
.SingleInstance();
var assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.SingleInstance();
}
}
CustomerData Modue:
public class CustomerDataModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<CustomerDataService>()
.As<ICustomerDataService>()
.InstancePerDependency();
builder.RegisterType<MappingEngine>().As<IMappingEngine>();
builder.Register(ctx =>
{
var configStore = new ConfigurationStore
(new TypeMapFactory(), MapperRegistry.AllMappers());
configStore.AddProfile<CustomerDataMapperProfile>();
return configStore;
})
.AsImplementedInterfaces()
.SingleInstance();
}
}
这里有一些额外的代码来展示我如何在Global.asax中加载这些模块
static IContainerProvider _containerProvider;
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}"
);
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
var builder = new ContainerBuilder();
builder.RegisterModule<UserAuthenticationModule>();
builder.RegisterModule<CustomerDataModule>();
_containerProvider = new ContainerProvider(builder.Build());
}
错误:
AutoMapper.dll中出现“AutoMapper.AutoMapperMappingException”类型的异常,但未在用户代码中处理 缺少类型映射配置或不支持的映射。\ r \ n \ r \ n映射类型:\ r \ n用户 - &gt;的usermodel
答案 0 :(得分:6)
我猜你遇到的问题是你正在注册两个ConfigurationStore
个实例但 MappingEngine
只需要一个构造函数参数。
当您在Autofac中注册多个内容时,它会“获胜”。所以当你解决a MappingEngine
时,它会选择这样的构造函数:
public MappingEngine(IConfigurationProvider configurationProvider)
这只需要一个配置提供程序(ConfigurationStore
实现IConfigurationProvider
),因此您只能获得一个。这意味着它相当于:
container.Resolve<IConfigurationProvider>();
你只会得到一个。如果您需要解决所有这些问题,则需要从Autofac解析IEnumerable<IConfigurationProvider>
,例如:
container.Resolve<IEnumerable<IConfigurationProvider>>();
但这不会解决你的问题,它只描述了我的想法。
你需要做的就是把你想要的东西分解一下。不是在每个模块中注册ConfigurationStore
,而是仅注册配置文件。像这样(缩短了可读性):
public class CustomerDataModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<CustomerDataMapperProfile>().As<Profile>();
}
}
public class UserAuthenticationModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<UserAuthenticationMapperProfile>().As<Profile>();
}
}
然后,您需要从模块中分解常见的AutoMapper注册。你不想双重注册。创建一个新模块,用于处理注册映射引擎,并对配置文件进行一些动态解析。
public class AutoMapperModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
// Register the common thing once, not in each module.
builder.RegisterType<MappingEngine>().As<IMappingEngine>();
// Here's where you dynamically get all the registered profiles
// and add them at the same time to the config store.
builder.Register(ctx =>
{
var profiles = ctx.Resolve<IEnumerable<Profile>>();
var configStore = new ConfigurationStore
(new TypeMapFactory(), MapperRegistry.AllMappers());
foreach(var profile in profiles)
{
configStore.AddProfile(profile);
}
return configStore;
})
.AsImplementedInterfaces()
.SingleInstance();
}
}
确保注册容器中的所有模块:
var builder = new ContainerBuilder();
builder.RegisterModule<UserAuthenticationModule>();
builder.RegisterModule<CustomerDataModule>();
builder.RegisterModule<AutoMapperModule>();
_containerProvider = new ContainerProvider(builder.Build());
现在,您应该在解析IMappingEngine
时注册所有配置文件。