Updated to AutoMapper 4.2.0, and following the migration guide available here: https://github.com/AutoMapper/AutoMapper/wiki/Migrating-from-static-API/f4784dac61b91a0df130e252c91a0efd76ff51de#preserving-static-feel. Trying to translate code on that page for StructureMap to Simple Injector. Can someone show me what this code looks like in Simple Injector?
StructureMap
public class AutoMapperRegistry : Registry
{
public AutoMapperRegistry()
{
var profiles =
from t in typeof (AutoMapperRegistry).Assembly.GetTypes()
where typeof (Profile).IsAssignableFrom(t)
select (Profile)Activator.CreateInstance(t);
var config = new MapperConfiguration(cfg =>
{
foreach (var profile in profiles)
{
cfg.AddProfile(profile);
}
});
For<MapperConfiguration>().Use(config);
For<IMapper>().Use(ctx => ctx.GetInstance<MapperConfiguration>().CreateMapper(ctx.GetInstance));
}
}
Simple Injector
?
答案 0 :(得分:13)
This would be the equivalent:
var totalQuestions = $('.questions').size();
var currentQuestion = 0;
$questions = $('.questions');
$questions.hide();
$($questions.get(currentQuestion)).fadeIn();
var nee = $('#next').click(function(){
$($questions.get(currentQuestion)).fadeOut(function(){
currentQuestion = currentQuestion + 1;
if(currentQuestion == totalQuestions){
alert('You have reached the end!');
} else {
$($questions.get(currentQuestion)).fadeIn();
}
});
});
var msg = (function(){
return function(){
d3.event.stopPropagation();
$("#div1").show();
}
})();
var whole = d3.selectAll('.v1');
var wholeCanvas = whole.append("svg").attr("width", 200).attr("height", 135);
wholeCanvas.append("circle").attr("cx", 50)
.attr("cy", 50)
.attr("r", 40)
.on("click", msg);
//want something like this
//var msg = (function(){
// if(questions)[0]
// return function(){
// d3.event.stopPropagation();
// $("#div1").show();
// }
// else if(questions)[1]
// return function(){
// d3.event.stopPropagation();
// $("#div2").show();
// }
// })();
答案 1 :(得分:3)
Simple Injector的IPackage接口看起来就像StructureMap的Registry类型一样。这是我使用的包,来自@Steven's answer:
using System;
using System.Linq;
using System.Reflection;
//
using AutoMapper;
//
using SimpleInjector;
using SimpleInjector.Packaging;
public class AutoMapperPackage : IPackage
{
public void RegisterServices(Container container)
{
var profiles = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(x => typeof(AutoMapper.Profile).IsAssignableFrom(x));
var config = new MapperConfiguration(cfg =>
{
foreach (var profile in profiles)
{
cfg.AddProfile(Activator.CreateInstance(profile) as AutoMapper.Profile);
}
});
container.RegisterSingleton<MapperConfiguration>(config);
container.Register<IMapper>(() => config.CreateMapper(container.GetInstance));
}
}
您需要添加SimpleInjector.Packaging包,然后在引导程序/配置代码中添加对container.RegisterPackages();
的调用。
基本上,从StructureMap真正改变的唯一事情就是最后两行。
答案 2 :(得分:0)
为了使用不同的MapperConfiguration对象映射多个IMapper,这似乎是一个反复出现的问题,我推荐以下方法,它甚至不需要重构mapper方法调用:
1)围绕IMapper接口创建通用包装器。这个包装器可以是一个接口或类,但显然你最终必须实现你的包装器,所以我将在下面展示具体的类。有这个包装器实现(或继承,如果你选择创建一个接口)IMapper接口,如下所示:
public class ProfileMapper<TProfile> : IMapper where TProfile : Profile
{
private IMapper mapper;
private Profile profile;
public ProfileMapper(TProfile profile)
{
this.profile = profile;
this.mapper = new MapperConfiguration( cfg => cfg.AddProfile( this.profile ) )
.CreateMapper();
}
}
泛型参数必须是“配置文件”的子类,因为从该配置文件开始,您将获得映射器配置。
2)在这个类中,只需将调用重定向到您在构造函数中创建的私有IMapper实例即可实现IMapper接口,如下所示:
public TDestination Map<TDestination>(object source)
{
return mapper.Map<TDestination>( source );
}
3)现在,您需要在Simple Injector中为您拥有的每个配置文件注册此ProfileMapper类的部分关闭实例。首先,通过获取从Profile继承的所有类,然后创建此部分关闭的实例,然后注册它。有几种获取所有Profile类的方法,但我接受了这个:
IEnumerable<Type> profileRegistrations =
from type in profileAssembly.GetExportedTypes()
where type.Namespace == "Namespace.Of.My.Profiles"
where type.BaseType.Equals( typeof( Profile ) )
select type;
foreach (Type profileType in profileRegistrations)
{
Container.RegisterSingleton( profileType, profileType );
Type mapperClosedType = typeof( ProfileMapper<> ).MakeGenericType( profileType );
Container.RegisterSingleton( typeof( ProfileMapper<> ), mapperClosedType );
}
此代码首先获取从Profile中继承的所有类型,位于所述命名空间中。然后对于每个Profile,我用SimpleInjector注册它(不是真的必要的,因为它们是具体的类型,因此可以由容器在运行中创建),然后我使用当前的部分关闭我的ProfileWrapper类的实例将配置文件作为通用参数,然后最后将我的封闭实例注册为Singleton。通过这种方式,您可以创建新的配置文件,而无需手动注册新的Wrappers。
就是这样。现在,您不必依赖和注入IMapper,而是为您的ProfileWrapper注入您想要使用的配置文件,如下所示:
ProfileMapper<ApplicationProfile> appProfileMapper;
ProfileMapper<MvcProfile> mvcProfileMapper;
ProfileMapper<GuestProfile> guestProfile;
等等。每个Wrapper都是使用不同的MapperConfiguration使用不同的配置文件创建的。由于包装器实现了IMapper,因此所有映射代码都保持不变。不需要重构方法调用,只需要依赖类型。
如果您创建BaseProfile,只需更改ProfileMapper中的泛型参数,以仅接受此BaseProfile的实例。