简体   繁体   中英

How to combine AutoMapper 5.2 with SimpleInjector for WCF service hosted in IIS

So far we've used the SimpleInjectorServiceHostFactory in the SimpleInjector.Integration.Wcf for our WCF services. This allowed us to avoid the typical "No parameterless constructor defined", when we have interfaces as parameters that SimpleInjector should resolve.

In the global.asax:

var container = new Container();
container.Options.DefaultScopedLifestyle = new WcfOperationLifestyle();
container.Register<IOurBusinessService, OurBusinessService>();
container.Verify();
SimpleInjectorServiceHostFactory.SetContainer(container);

To configure/register AutoMapper we would call some code to register it in the Global.asax, like so:

var cfg = new MapperConfigurationExpression();
cfg.CreateMap<SomeObject, SomeObjectDTO>();
Mapper.Initialize(cfg);
Mapper.Configuration.AssertConfigurationIsValid();

However it seems that when our Web-Services are called directly with a net.tcp endpoint, there is sometimes no more AutoMapper registered. This seems to be the case as the code in Global.asax in Application_Start is never executed, when the WCF service is requested directly.

We currently try to derive from ServiceHostFactory and register both AutoMapper and SimpleInjector in our overridden CreateServiceHost method. This however does give us again the "No parameterless constructor defined" error.

Do you have any solution or best practices?

Is your configuration correct?

You can create the Mapper at startup and then inject it as a singleton dependency:

Create the Mapper ( code found here ):

var config = new MapperConfiguration(cfg => {
    cfg.AddProfile<AppProfile>();
    cfg.CreateMap<Source, Dest>();
});

var mapper = config.CreateMapper();
// or
IMapper mapper = new Mapper(config);

Register as singleton:

var container = new Container();

// Registrations
container.RegisterSingleton(typeof(IMapper), mapper);

To inject:

public class MyClass 
{
    private readonly IMapper mapper;
    public MyClass(IMapper mapper)
    {
        this.mapper = mapper;
    }
}

I am not sure if this will solve you "No parameterless constructor" issue, but this is a good way to handle the AutoMapper injection. If It does not solve the problem, let me know.

Let me know if you have questions.

One way to make the above scenario work was to derive from SimpleInjectorServiceHostFactory and do the override there.

public class OurServiceHostFactory : SimpleInjectorServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        // ConfigInit is a static class with a simple check, to see if the configuration was already initialized
        // the same method ConfigInig.Configure() is also called in the Global.asax in Application_Start
        ConfigInit.Configure();
        return base.CreateServiceHost(serviceType, baseAddresses);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM