Reputation: 318
I'm sure that this questions has been asked several times, but I'm stuck in a rut on this one. I am attempting to automap properties from EF objects to defined interfaces. I'm using simple injector as my choice of IOC framework. (win forms)
I've registered my interfaces within the program.cs ..
container = new Container();
container.Register<IBob, Bob>();
...
and pass an instance of the container into the class where I'm doing the automapping ...
public ModelService(IDataRepository repo, Container container)
{
// create a reference to the repository
this.Repository = repo;
var config = new MapperConfiguration(cfg =>
{
// pass the reference into the constructor service.
qcfg.ConstructServicesUsing(type => container.GetInstance(type));
cfg.AddProfile<ModelConfig>();
});
mapper = new Mapper(config);
}
The profile class looks a little bit like this ...
public class ModelConfig : Profile
{
public ModelsConfig()
{
// mapping definition for product buy
this.CreateMap<Entity.BobEF, IBob>()
.ForMember(destination => destination.UniqueIdentifier, option => option.MapFrom(source => source.BobID))
.ReverseMap();
}
So I was expecting automapper to use the container to create a concrete class for IBob given that this has already been declared within the BI bootstrapping and it should be using the "container.GetInstance()" method to resolve the interface, however what I'm actually getting in a proxy representation of the IBob class with a type of Proxy_MyProject.IBob_232342
I really don't understand the automapper documentation for this as I'm new to using automapper.
Any HELP very much appreciated.
Regards,
Tim
Edit: (Example of model classes being used)
// shows the basic interface for a product
public interface IProduct : IModel
{
string Name { get; set; }
ISupplier Supplier { get; set; }
}
// shows the concrete implementation including the
// exposed property being of type ISupplier
public class Product : Model, IProduct
{
public string Name
{
get;
set;
}
public ISupplier Supplier
{
get;
set;
}
}
Upvotes: 0
Views: 475
Reputation: 3516
ConstructServicesUsing
by itself only applies to value resolvers, member value resolvers, type converters etc. Unrelated to what you need. You want:
CreateMap<Entity.BobEF, IBob>().ConstructUsingServiceLocator();
That will also cause you destination objects to be constructed the same way. But I have to agree with @JoepVerhoeven, it sounds like over-engineering.
Upvotes: 3
Reputation: 318
The answer provided by @Lucian Bargaoanu is correct, but this has required a combination of both ConstructServicesUsing
and ConstructUsingServiceLocator
. I had read the documentation here .. enter link description here but hadn't understood this mean that we should utilise the additional ConstructUsingServiceLocator
on the mapping declarations.
Example:
// Or marker types for assemblies:
var config = new MapperConfiguration(cfg =>
{
// pass the reference into the constructor service.
cfg.ConstructServicesUsing(type => container.GetInstance(type));
//cfg.ConstructServicesUsing()
cfg.AddProfile(new BusinessModelsConfig(this.Repository.Context));
});
This config is contained within the BusinessModelsConfig ..
// mapping definition for product buy
this.CreateMap<Entity.ProductBuy, IProductBuy>()
.ForMember(destination => destination.UniqueIdentifier, option => option.MapFrom(source => source.ProductBuyID))
.ForMember(destination => destination.Status, option => option.MapFrom(source => source.BuyStatus))
.ForMember(destination => destination.TimeStamp, option => option.MapFrom(source => source.ts))
.ConstructUsingServiceLocator();
For those needing to also map back to the entities so that change can be reflected within the persistence layer, this article proved invaluable in understanding how this can be achieved, although automapper may not be the best tool for this. This article is rather old and I would welcome any information which offers a different perspective.
Upvotes: 0
Reputation: 128
The reason why automapper returns a Proxy object is because you are mapping a class to an interface and automapper does not know which implementation of IBob
to use.
Upvotes: 1