Dependency Injection to resolve dependency with runtime data - c#

I am using simple injector for my web api project. I have a service which requires a session token in order for it to instantiate.
public class CustomerService
{
public CustomerService(Auth auth, IRepositoryFactory repositoryFactory)
{
// make post call to another web api for validation
SomeWebApiCallToValidateAuth.vaildate(auth);
}
}
So for this service, it requires an auth token and a repositoryFactory. I want it to be able to inject the auth parameter (which comes from the http web request) and at the same time to resolve the repository factory with the specified implemented thats registered to the container.
But I am not sure how to register this with simple injector or if there is a way around it. Any help would be great. Thanks.

Your current approach has several downsides:
You inject runtime data into the constructor of your component, which can lead to complications.
You make use of an Abstract Factory, which is often not the best abstraction.
Your constructor invokes validation, while it should do nothing other than storing its incoming dependencies. This way you can compose your object graphs with confidence.
Concerning the factory: Inject an IRepository rather than an IRepositoryFactory. This might require you to hide the real repository behind a proxy, as explained here.
Concerning the Auth value, it depends on the need, but if the Auth value is an important part of the API of CustomerService, this justifies adding Auth as argument on the methods of CustomerService. If it is an implementation detail, inject an IAuthProvider abstraction of some sort that allows you to retrieve the value at runtime (after the object graph is built). Again, this all is described in this article.

Related

How does MediatR know which handler to call?

I'm learning MediatR and I have a problem connecting the Controller to the Handler.
Controller:
[HttpGet]
public async Task<List<PersonModel>> Get()
{
return await _mediator.Send(new GetPersonListQuery());
}
My understanding is that the Controller will invoke the Handler using _mediator.Send(). However, the argument for Send is not the Handler but the Command / Query.
In Visual Studio, I checked how many reference there are to the Handler and it says Zero. So how does the MediatR know which particular handler to call?
Thanks.
MediatR makes heavy use of generic types in order for its mechanism to work. As you probably noticed from using it, you are required to use certain interfaces in the right way in order for your requests and handlers to be usable for MediatR.
Let’s take your example to explain how this all works:
await _mediator.Send(new GetPersonListQuery());
In order for GetPersonListQuery to be accepted, it will need to implement the marker interface IRequest<TResponse> (where TResponse stands for any response type). This also works if your request class implements this interface implicitly, e.g. by implementing IRequest instead (which is a shortcut for IRequest<Unit>).
So GetPersonListQuery implements the request interface which makes it a valid request type for MediatR. In order for a handler to be able to respond to it, that handler will now need to implement IRequestHandler<GetPersonListQuery> (again, implicitly is also ok).
So you now have this constellation:
public class GetPersonListQuery : IRequest { }
public class PersonListHandler : IRequestHandler<GetPersonListQuery> { }
From the point of view of using MediatR, this is usually all that you will need to do. MediatR will connect these two, so the handler runs when your request is sent.
It does that by relying on dependency injection, most commonly the Microsoft.Extensions.DependencyInjection container. The dependency injection container basically works by collecting a list of service registrations that contain both a service type and an implementation type. When the container then needs to resolve an instance of the service type, it will look up the service registration for that and construct an object by instantiating the implementation type.
In our example, the PersonListHandler is the implementation type, and the IRequestHandler<GetPersonListQuery> interface is the service type. So when something requests an IRequestHandler<GetPersonListQuery> from the DI container, the DI container will respond to it with an instance of PersonListHandler.
So MediatR doesn’t actually do that much; in fact, the most of its complexity comes from abstracting the dependency injection container so that it can work with others as well. But if you wanted to implement this with a specific DI container in mind, the implementation could look like this (simplified pseudo-code):
public Task<object> Send(IRequest request)
{
var requestType = request.GetType(); // GetPersonListQuery
var handlerType = CreateHandlerType(requestType); // IRequestHandler<GetPersonListQuery>
var handler = GetService(handlerType); // PersonListHandler object
return await handler.Run(request);
}
So the magic mostly boils down to the magic from the DI container, with MediatR making use of the container’s ability to resolve services.
But how does the DI container know which handlers to register? That is pretty easy to explain: When you do services.AddMediatR(…) then you are essentially telling MediatR to actively scan the assembly for all types that implement IRequestHandler<T> and register those with the dependency injection container. So just by adding a new request handler to your project, AddMediatR will pick that up when the application launches, making it available to the DI container and by that to the MediatR mediator implementation.
Since MediatR relies on the DI container for resolving the request handlers, this also gives you a direct answer to the other question you had: What happens when you have multiple request handlers for one request type?
The DI container by default will only ever give you one instance when resolving a service. This means that when you have multiple handlers implementing IRequestHandler<GetPersonListQuery>, you will only get one of them. Usually, the DI container will use the latest service registration to resolve a service. So if you register two implementation types for the same service type, the later registration will overwrite the former.
As you don’t register the services yourself with AddMediatR, you cannot actively control the registration order. Since it’s iterating over all types, I would expect the registration order to be alphabetically, but I wouldn’t rely on that. If you want a specific handler to run, you should just avoid having a different handler in the same assembly.
Note that there are cases where multiple service registrations do work: The whole notification concept in MediatR (INotification and INotificationHandler) is made for the ability for multiple handlers to exist. This is using a different feature with the dependency injection container which allows you to resolve instances for all service registrations. So if you have two handlers for the same notification, both handlers will be returned by the DI container and MediatR can call them both. The rest of the handling in MediatR is really the same as with requests though.
when you create Query/Command, you use IRequest interface. then in handler you call IRequestHandler<Query/Command>. here they make relation.
At runtime, MediatR scans your project for classes implementing IRequestHandler<T> and makes note of each of them (including your IRequestHandler<GetPersonListQuery>). When you use _mediator.Send, it matches the type of the parameter to a matching IRequestHandler it found during app startup.

Simple Injector registers only one parameter of a class having multi-parameterized constructor

I'm a part of team creating a "sort of" message based framework where people can register their message handlers with the dependencies they have for their handlers.
The worker, will receive messages and invoke relevant handlers. Since the handlers have dependencies so we are passing IDependecyResolver implementation through the worker constructor. Worker uses this abstraction to create these handlers.
The users of our framework can use any DI container they like so all they have to do is to implement certain interfaces that provide abstraction to their favorite DI container. My job is to provide an implementation for SimpleInjector so for our framework, SimpleInjector is supported out of box.
The problem I'm facing is that even though I register an SimpleInjectorDependencyResolver in the container, the container is not able to resolve IDependencyResolver implementation at runtime and I get this.
This is the exception I get.
ActivationException: The constructor of type ReactiveWorker<HelloModuleBase> contains the parameter with name 'map' and type IMessageHandlerMap<HelloModuleBase> that is not registered. Please ensure IMessageHandlerMap<HelloModuleBase> is registered, or change the constructor of ReactiveWorker<HelloModuleBase>.
Here is my code for registration:
registrant.Register<IDependencyResolver>(LifeSpan.Scoped);
registrant.Register<IMessageHandlerMap<TChildModule>>(t0, LifeSpan.Scoped);
the worker needs both, a message-handler map and a dependency resolver.
This is my class with parameterized constructors:
public sealed class ReactiveWorker<TOwnerModule>: IWorker
{
readonly IMessageHandlerMap<TOwnerModule> _map;
readonly IDependencyResolver _resolver;
public ReactiveWorker(IMessageHandlerMap<TOwnerModule> map, IDependencyResolver resolver)
{
_map = map;
_resolver = resolver;
}
}
I hope everyone is able to understand the scenario.
I am trying to create an abstract class/layer for all dependency resolvers which are/will be used in my project.
This sure sounds like you are applying the Service Locator anti-pattern. You might want to double check if what you're doing is Dependency Injection or Service Location and prevent Service Location whenever possible.
Furthermore, from the posted registrations, it looks like if you are trying to implement batch-registration behavior. Simple Injector does contain this functionality out of the box, and it is worth investing into Simple Injector's API to see whether you can let the tooling do the job.
Your Helper.FindConcreteImplementationsOf, for instance, looks a lot like Simple Injector's Container.GetTypesToRegister method. It returns concrete implementations of a given type, for instance:
Type[] types = container.GetTypesToRegister(typeof(IMessageHandler<>), asm);
Simple Injector also allows for mapping open-generic abstractions to open-generic implementations. Using your MessageHandlerMap<T>, for instance, you can do the following:
container.Register(
typeof(IMessageHandlerMap<>),
typeof(MessageHandlerMap<>),
Lifestyle.Scoped);
This ensures that a closed version of MessageHandlerMap<T> is created, every time a closed version of IMessageHandlerMap<T> is requested. This does, however, rely on Simple Injector's Auto-Wiring ability, which means that Simple Injector must be able to inject all dependencies into the class's constructor. This might mean you have to change the constructor of MessageHandlerMap<T> in order to let Simple Injector Auto-Wire the type.
Because its unclear to me what the function of MessageHandlerMap<T> is and how its implementation looks like, I'm unable to fully grasp what you're trying to achieve, and can't, therefore, not give you more specific advise about making changes to your design.
Good luck.

Manually registering web api controllers in simple injector

I'm using Umbraco which has a lot of custom web API controllers under the hood. I would like to ignore them in simple injector and just manually register my own web api controllers.
Should I register the controller's lifestyle as transient or scoped? Web api controllers implements IDisposable, but if I understand it correctly, simple injector registers them as transient when using container.RegisterMvcControllers(). If they should be transient when using web api too? If so, I suppose I have to suppress the disposable warning?
How would the registration look like? If I simply do a container.Register<MyController>(Lifestyle.Transient) and my controller injects another registered interface, i.e. public MyController(IMyRegisteredInterface foo), it will throw the exception Make sure that the controller has a parameterless public constructor.
I would like to ignore them in simple injector and just manually register my own web api controllers
You can easily ignore them, while still enjoying batch-registration by supplying only the assemblies you wish to be scanned to the RegisterWebApiControllers method as follows:
container.RegisterWebApiControllers(httpConfiguration,
typeof(MyApiController).Assembly);
Should I register the controller's lifestyle as transient or scoped?
You can do both, but registering them as transient is typically the easiest because that prevents that all its dependencies should be Scoped as well. Downside of this is that, since ApiController implements IDisposable, it means that you will have to suppress the DisposableTransientComponent diagnostic warnings. This is actually a design flaw in Web API, because base classes and interfaces should typically not implement IDisposable. This warning can be suppressed, because Web API will ensure disposal.
Simplest thing to do is to use the batch-registration facility supplied by the RegisterWebApiControllers method, because it will suppress this warning for you automatically.
Make sure that the controller has a parameterless public constructor.
Make sure you follow the Web API Integration Guide, and especially use the SimpleInjectorWebApiDependencyResolver; it will ensure that Controllers are resolved by Simple Injector.

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.

Reducing dependencies with SignalR, NHibernate and Ninject

An architectural question. I've got a nicely de-coupled MVC3 solution with a few projects that's working rather well.
Proj.Core - interfaces for data classes and services
Proj.Services - interfaces for model services
Proj.Data.NH - implementations of the data interfaces
Proj.Services.NH - implementations of the data / model services
Proj.Infrastructure - setting up Ninject and NHibernate
Proj.Tests - unit tests
Proj.Web - the MVC project
I've set up NHibernate to be session per request in the infrastructure project, so Proj.Web doesn't need to reference NHibernate (or Ninject, for that matter). I'm now introducing SignalR, which works really nicely for a quick chat app. I've put a SignalR hub in the web project. I now want to persist the chat messages in the database, which has confused me somewhat.
I want to use a service (let's call it PostService), so the SignalR hub doesn't have a dependency on NHibernate. My other services are injected into the controllers' constructors, and the session is injected into the services' constructors.
As the SignalR hub hangs around, unlike controllers, PostService (injected into the constructor as an IPostService) can't have a session injected into its constructor, as there won't be a session. If there was, it would hang around forever, which would be far too long a time for a transaction.
I could inject the session factory into the PostService, and each method could use a transaction, e.g.
private void WithTransaction(Action<ISession> action)
{
using (var session = _sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
action(session);
tx.Commit();
}
}
public IPost Post(string message)
{
WithTransaction(session =>
{
session.Save(new Post(message));
});
}
The hub will then call _postService.Post(message);
However, once the Post method does more things, I'll want to use some of my existing services to do the things, as they've already been written and unit tested. As the session is created in the method, I can't have the services injected into the PostService constructor, as they accept a session into their constructors.
So, I guess I have the following options, but I'm not sure if a) this is a complete list, or b) which is the best option:
I. Inject an IDependencyResolver into the PostService constructor, and create the services I need in the Post method, passing in the session to the constructor. There's an IDependencyResolver in System.Web.Mvc and in SignalR, so this would (depending on which project PostService resides) introduce a dependency on either library.
II. Modify the services so each method that uses a session has one passed in as a parameter. Overload this without the session parameter, and call the new one. The MVC service calls would use the first, and the PostService would use the second e.g.
public void SaveUser(IUser user)
{
Save(_session, user);
}
public void SaveUser(ISession session, IUser user)
{
session.Save(user);
}
III. Don't use the existing services. Have the PostService do it's own thing, even if there is a bit of duplication (e.g. getting user details etc.)
IV. Remove the ISession from the services' constructors, and pass it in to each method (and deal with the Controllers' accordingly.
V. Something else.
I guess I'm leaning towards the first one, but I'm not sure where PostService would live. If it goes in Proj.Services.NH, then I'd have to introduce a dependency on System.Web.Mvc or SignalR, which I don't want to do. If it lives in Proj.Web, then I'd have to introduce a dependency on NHibernate, which I also don't want to do. It doesn't belong in Proj.Infrastructure, as it is application code. Should it have it's own project with dependencies on everything, or is there a better way?
I would use some sort of auto factory for the additional services you need. So you would write your PostService constructor as:
public PostService( Func<INeededService1> factory1,Func<INeededService2> factory2 ...)
{
...
}
and then use this extension to have these factory automatically working ( by querying the container ).

Categories