How to combine SimpleInjector for WCF and Web API - c#

I'm having a web project that hosts both WCF and Web API V2 ApiControllers.
Both should benefit from using SimpleInjector.
There are 2 different nuget packages for the 2 techniques:
SimpleInjector.integration.WebApi
SimpleInjector.Ingegration.Wcf
As in the given case registrations should be identical for both, what is the best way to approach this?
Should I create 2 different containers, since the scope will anyway be valid only as long as the requests are open?
I currently implemented the following, to use the correct ScopedLifestyles:
public static void ConfigureForWCF(Container container)
{
container.Options.DefaultScopedLifestyle = new WcfOperationLifestyle();
RegisterImplementations(container);
}
public static void ConfigureForWebAPI(Container container)
{
container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
RegisterImplementations(container);
}
public static void RegisterImplementations(Container container)
{
// registrations for both WCF and Web API in here
container.Register<IMyInterface, MyClass>();
and I know call them like that:
// container for WCF
var containerWCF = new Container();
SimpleInjectorConfiguration.ConfigureForWCF(containerWCF);
containerWCF.Verify();
// use the container for WCF
SimpleInjectorServiceHostFactory.SetContainer(containerWCF);
// container for Web API
var containerWebAPI = new Container();
SimpleInjectorConfiguration.ConfigureForWebAPI(containerWebAPI);
// this doesn't currently make sense for me as the controllers inheriting from ApiController get registered as Transient
//containerWebAPI.RegisterWebApiControllers(GlobalConfiguration.Configuration);
// instead I will register the Controllers manually
containerWebAPI.Verify();
// use the container for Web API
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(containerWebAPI);
Would it be possible to use the same Container eventually?
(calling Verify on both containers also doesn't make sense as long as they have identical registrations)

You've basically got 3 options:
Use two container instances
Use one container instance with a hybrid lifestyle that mixes the WebApiRequestLifestyle and WcfOperationLifestyle.
Use one container and use the same lifestyle for both WCF and Web API. This would typically be the AsyncScopedLifestyle.
Whether or not it is okay to have two containers depends on several values, such as the amount of services that should exist exactly once across the whole AppDomain. When you have 2 container instances, each get their own singleton instance, so you should provide each container with an existing instance. This can be troublesome, but in most cases it should not be a problem for a container to get its own singleton instance.
On the other side will having 2 containers mean that you will have to use some shared logic that can populate the registrations that both container instances share. This can complicate things.
On the other hand does having two containers allow both services to run in an isolated fashion, which can be beneficial.
If you choose to have one container instance, the use of a Hybrid lifestyle would be the most obvious solution, especially since the scoping technology used by WCF is different (based on ThreadScopedLifestyle) from the Web API scoping technology (which is based on AsyncScopedLifestyle). So, easiest solution is to register them as hybrid as follows:
container.Options.DefaultScopedLifestyle = Lifestyle.CreateHybrid(
defaultLifestyle: new WebApiRequestLifestyle(),
fallbackLifestyle: new WcfOperationLifestyle());
With this configuration, Simple Injector will use WebApiRequestLifestyle when there is an active Web API scope (which means a AsyncScopedLifestyle scope). In the absence of such scope, it will fallback to using the WcfOperationLifestyle.
This will be the easiest solution in case you wish to have one container.
The last option is to use one particular scoped lifestyle for both the WCF and the Web API application. Since Web API is inherently asynchronous, the only obvious lifestyle to use is AsyncScopedLifestyle. With ASP.NET Core we are actually moving away from custom framework-specific lifestyles and primarily use AsyncScopedLifestyle instead.
Although you can both use AsyncScopedLifestyle and WebApiLifestyle interchangeably in a Web API application, this doesn't hold for WCF. That's because the WCF integration package uses a technique that is similar to the ThreadScopedLifestyle, but uses its own implementation.
Although you can use the AsyncScopedLifestyle on single-threaded applications as well, you will have to replace part of the infrastructure for WCF that currently starts the WCF scope, to make it start an async Scope instead.
Since this is a bit more work to do, I would opt for either using 2 containers, or use the hybrid lifestyle.

Related

DI in Service Fabric Service Remoting

I have a Service Fabric application with one service which is exposed to Internet (GatewayService) through an ASP.NET Web API and a couple of internal services not exposed to the Internet (let's call one of them InternalService). So far, InternalService is also an ASP.NET Web APIs, so InternalService.cs has a CreateServiceInstanceListeners() method which looks like this:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[] {
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
WebHost.CreateDefaultBuilder()
.UseStartup<Startup>()
.ConfigureServices((context, services) => { services.AddSingleton(serviceContext); })
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build()))
};
}
The Startup class (in Startup.cs) for InternalService configures some services, such as adding a SQL DbContext to the Dependency Injection system, and of course setting up ASP.NET with AddMvc() etc. I have a couple of ApiControllers which expose the API.
This works, BUT I don't get any real type safety with this, and it generally makes development a bit cumbersome, needing to deserialize the result manually in my GatewayService before manipulating it. So I decided to go with SF's Service Remoting instead, resulting in a CreateServiceInstanceListeners() method which looks like this:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return this.CreateServiceRemotingInstanceListeners();
}
Then I copied all the logic from the controllers into InternalService.cs too, but this lead to an issue: I don't have access to my DbContext anymore, because it was injected into the constructor of the ApiController, instantiated by ASP.NET according to the rules set in the Startup class, which isn't used anymore.
Is there a way for me to use Startup in the same way when using Service Remoting?
Can I separate the API into multiple classes, in the same way as ApiControllers are separated into multiple classes? I feel like having all exposed methods in the same class will be quite a hazzle.
I know this has already an accepted answer, but I want to add my two cents.
As you have realized, remoting has two major differences compared to WebApi:
Given a remoting interface, you have a single implementation class
The remoting implementation class is a singleton, so, even if you use DI as explained in the accepted answer, you still can't inject a DbContext per request.
I can give you some solutions to these problems:
This one is simple: create more interfaces. You can add as many remoting interfaces as you want in a single service fabric service. So, you should split your remoting API into smaller interfaces with groups that make sense (interface segregation). But, I don't think you should have many, because that would probably mean that your microservice has too many responsibilities.
A naive approach to having dependencies per request is to inject factories into the remoting class, so you can resolve and dispose dependencies in every method instead of by constructor injection. But I found a much better approach using Mediatr, which might not seem trivial, but once set up it's very easy to use. The way it works is you create a little helper class that gets an ILifetimeScope (as you use Autofac) in the constructor and it exposes an Execute method. This method will create a child LifetimeScope, resolve Mediatr and send a WrapperRequest<TRequest> (the wrapper is a trick so that the remoting input and output objects don't have to depend on Mediatr). This will allow you to implement a Handler class for each remoting operation, which will be resolved per request so that you can inject the dependencies in the constructor as you do with a WebApi controller.
It might sound confusing if you are not familiar with Mediatr and Autofac. If I have time I'll write a blog post about it.
You can use Autofac, there's an entire page that explains how to set it up:
Add the Autofac.ServiceFabric nuget package
Configure DI:
// Start with the trusty old container builder.
var builder = new ContainerBuilder();
// Register any regular dependencies.
builder.RegisterModule(new LoggerModule(ServiceEventSource.Current.Message));
// Register the Autofac magic for Service Fabric support.
builder.RegisterServiceFabricSupport();
// Register a stateless service...
builder.RegisterStatelessService<DemoStatelessService>("DemoStatelessServiceType");
// ...and/or register a stateful service.
// builder.RegisterStatefulService<DemoStatefulService>("DemoStatefulServiceType");
using (builder.Build())
{
ServiceEventSource.Current.ServiceTypeRegistered(
Process.GetCurrentProcess().Id,
typeof(DemoStatelessService).Name);
// Prevents this host process from terminating so services keep running.
Thread.Sleep(Timeout.Infinite);
}
check out the demo project.

ASP.NET Core 2.0 service life time

I have api application ,service & repository class library application . Service part i write business logic and repository only communicate for database. My question which type of dependency is best for repository and service .
services.AddScoped<ITicketRepository, TicketRepository>();
services.AddTransient<ITicketRepository, TicketRepository>();
services.AddSingleton<ITicketRepository, TicketRepository>();
Like always, it depends. My suggestion is the following:
Scoped: in my opinion, there can be two main reasons for using this:
Your dependency has a dependency which has a scoped lifetime. In this case, you cannot use singleton, but can use scoped or transient. Which one you should take is based on the other criteria.
Your dependency has some state which makes it unsuitable to be used in singleton scope, but it is heavyweight enough that you don't want to register it as transient. Another possibility is that, again, it cannot be used in singleton scope, but it is fine to share the same instance per request (scope) and you don't want to add the overhead of constructing new ones if two types depend on the same thing and both of them are used to serve a single request.
Transient: this is the simplest approach. Every time an instance of a dependency registered in this manner is required, a new instance is created. This is probably the most foolproof, but can cause serious overhead if its usage is not justified. #Tony Ngo pointed out in his answer, quoting from the official docs, that this works best for lightweight, stateless objects, but I'd argue that statelessness is a very good indicator that you may want to use singleton lifetime as statelessness guarantees that the same object can be used concurrently just fine. Whether you choose transient or singleton lifetime in this case really depends whether you care about such aspects of performance like GC cost, which is obviously much, much higher if you create a new instance every time such a dependency is required, even if you could avoid doing so. Having said that, transient is used by many developers in this scenario as well, probably due to its foolproofness, or simply because they tend to think about it as the default choice.
Singleton: the points above basically summarize this one: you can choose this when there is absolutely no reason to create a new instance of the dependency for each request (scope) or to use an other dependent instance. Note that like said before, you cannot use singleton lifetime when the type has a dependency which is registered as scoped.
Transient lifetime services (AddTransient) are created each time
they're requested from the service container. This lifetime works best
for lightweight, stateless services.
Scoped lifetime services (AddScoped) are created once per client
request (connection).
Singleton lifetime services (AddSingleton) are created the first time
they're requested (or when Startup.ConfigureServices is run and an
instance is specified with the service registration).
So depend on what you need you can choose correct liftetime you can view it more here
I am assuming your TicketRepository is depend on your EF Core DbContext and your
EF Core DbContext is by default registered as ScopedSerivce so here registering TicketRepository as SingletonService is out of consideration as because:
It's dangerous to resolve a scoped service from a singleton. It may cause the service to have incorrect state when processing subsequent requests.
For more details: Dependency injection in ASP.NET Core-Service lifetimes
Now you can choose between AddTransient<> and AddScoped<> where:
Transient lifetime services (AddTransient) are created each time they're requested from the service container. This lifetime works best for lightweight, stateless services.
Scoped lifetime services (AddScoped) are created once per client request (connection).

Retrieving the instance of an already-registered service in Mvc Core .Net Dependency Injection

I have the following code snippet in my application:
services.AddScoped<IMyInterface, MyService>();
services.AddSingleton<IYourInterface, YourService>();
Due to some environment initialization process, I have to be able to obtain the singleton instance of IYourInterface within Startup class to call the service to read a couple of configuration entries from a remote server and populate them. How can I achieve this goal considering the fact that I am using .Net Core's built-in DI framework?
The way to do this to create this instance manually up front as follows:
var service = new YourService();
services.AddScoped<IMyInterface, MyService>();
services.AddSingleton<YourService>(service);
Just as it is wise to separate the registration process from use (as the Microsoft.Extensions.DependencyInjection library correctly forces), this kind of separation is important between loading/building configuration and making the container registrations. Doing register-resolve-register is unsupported by libraries like MS DI, Autofac and Simple Injector, because it can lead to lots of complexity and subtle bugs.

Resolve dependencies in ASP.NET Web API with Simple Injector and IHttpControllerActivator

I am currently using Simple Injector to resolve dependencies into my Asp.Net Web Api projects.
From the documentation you can configure it like that:
protected void Application_Start() {
// Create the container as usual.
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
// Register your types, for instance using the scoped lifestyle:
container.Register<IUserRepository, SqlUserRepository>(Lifestyle.Scoped);
// This is an extension method from the integration package.
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
container.Verify();
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(container);
// Here your usual Web API configuration stuff.
}
The main points here are to register the Web Api controllers and set a custom dependency resolver.
However I've just read these article from Mark Seemann on how to configure dependency injection in Asp.Net Web Api:
Dependency Injection and Lifetime Management with ASP.NET Web API
Dependency Injection in ASP.NET Web API with Castle Windsor
From these articles, I've learnt that there is a better option than implementing IDependencyResolver to resolve Web Api dependencies.
This other option is to create an implementation of the IHttpControllerActivator that acts as an Adapter over the IoC Container.
Here is the implementation I've coded using SimpleInjector:
public class SimpleInjectorControllerActivator : IHttpControllerActivator
{
private readonly Container _container;
public SimpleInjectorControllerActivator(Container container)
{
_container = container;
}
public IHttpController Create(HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
request.RegisterForDispose(_container.BeginExecutionContextScope());
return (IHttpController)_container.GetInstance(controllerType);
}
}
and in the Application_Start method, I've replaced this line:
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(container);
by this line :
GlobalConfiguration.Configuration.Services.Replace(
typeof(IHttpControllerActivator),
new SimpleInjectorControllerActivator(container));
I would like to know if the implementation of the IHttpControllerActivator is valid and also if this approach is valid and will work as good as the normal one ?
Yes, your implementation is valid.
Only be careful not to use both the SimpleInjectorWebApiDependencyResolver and the SimpleInjectorControllerActivator in the same application. Both start an ExecutionContextScope which could lead to having two scopes within the same web request, so they are mutually exclusive.
A general advantage of using a controller activator over the dependency resolver is that the dependency resolver contract forces the adapter to return null when a service can't be created. This is a very common problem that developers run into, and it often causes the confusing controller does not have a default constructor exception. This problem does not exist when using an IHttpControllerActivator, since the contract forces you to return a value or throw an exception.
The Simple Injector Web API integration project however, prevents this problem with dependency resolver, by never returning null (but throwing an exception instead) in case the requested service is an API controller (and thereby implicitly breaking the IDependencyResolver's contract).
An advantage of using the SimpleInjectorDependencyResolver is that it becomes easier to create message handlers that operate within the execution context scope, since you can trigger the creation of this scope by calling request.GetDependencyScope() method. With the current implementation, the scope just gets started at the time that the controller gets created, which is after you run the handlers. Changing this isn't that hard, but involves changing your controller activator and have an outermost handler that starts the execution context scope (or again falling back on a dependency resolver that manages the execution context scope).
One of the arguments of Mark Seemann is that it becomes hard to pass context around, which is a very valid point, as long as your components don't require this context during construction. But this is not a problem you'll experience when using Simple Injector, because there is an extension method that helps you with accessing the HttpRequestMessage. So although the IDependencyResolver abstraction isn't designed for getting the contextual information, there are ways to get this contextual information.
In the past we decided to go with an adapter for the IDependencyResolver, mainly because this was the common practice with all DI containers. I partly regret this decision, but using the SimpleInjectorDependencyResolver is now usually the easiest way of plugging in Simple Injector into Web API. We considered adding a SimpleInjectorControllerActivator as well, but this had no practical benefit for most users, while we still would had to document when to use what. So we decided to stick with the dependency resolver adapter; an adapter for the activator is easily created for anyone who needs it, as you can see.
For ASP.NET Core however, we went into a different direction, and as you can see in the documentation, the integration package actually contains a SimpleInjectorControllerActivator out of the box. In ASP.NET Core, the controller activator is the perfect interception point and due to the OWIN-like pipeline, a scope can be easily wrapped around a request. So with ASP.NET Core, the advised practice is to use the controller activator as interception point.

Limit instance lifetime to a single iteration

I'm working on a web application that uses a couple of services to synchronize data with external resources. The application and the services share the same data layer and use Castle Windsor to implement IoC.
In the web application there is the a PerWebRequest lifestyle which limits the lifetime of an instance to the lifetime of a request. I want to use something similar in the services.
The services are triggered every once in a while to do the synchronization. I want the services and repositories in the datalayer to be singletons within the a single iteration of the service, similar to the PerWebRequest lifestyle in the web application.
What I've come up with is the concept of a Run. A run is a single invocation of the synchronization code within the service. That looks like this:
using( _runManager.Run() )
{
var sync = _usageRepoFactory.CreateInstance();
sync.SynchronizeUsage();
}
The implementation of IRun will release all instances with the PerRunLifeStyle resolved since it's creation when it is disposed, at the end of the using block.
This code looks quite clean, but I wonder if there is a better way of doing this. I have tried using child containers but found these rather 'heavy' after profiling the solution.
Any feedback is welcome. If needed I can post the IRun implementation as well.
Update
Based on the comments I've cleaned up the code a bit. I've introduced a new service IRunManager which is basically a factory for IRun. I've also started using a factory to get rid of the ServiceLocator invocation.
Take a look at this contextual lifestyle

Categories