Does MediatR walk all classes in the project looking for matches? - asp.net-core

There are two parts to this question. First I am going to explain what I think is happening? And then second, in that explanation, I want to verify how it is finding a class it needs.
This is from Nick Chapsas' program Write cleaner APIs in .NET 7 with MediatR.
This code handles a request using MediatR as follows.
n program.cs it has:
app.MediateGet<ExampleRequest>("example/{name}");
which is called via the extension function:
public static WebApplication MediateGet<TRequest>(
this WebApplication app,
string template) where TRequest : IHttpRequest
{
app.MapGet(template, async (IMediator mediator,
[AsParameters] TRequest request) => await mediator.Send(request));
return app;
}
where IHttpRequest is defined as:
public interface IHttpRequest : IRequest<IResult>
{
}
So what has occurred from all this is me have an app.MapGet() call for the url "example/{name}" and it will be handles by MediatR.
ExampleRequest.cs is a POCO containing the URL parameters, etc.
The handler must implement the interface IRequestHandler<ExampleRequest, IResult>. When that url is requested, it will instantiate the appropiate class and call its Handle() method passing in the ExampleRequest and getting a Task returned.
Question 1: Is that correct?
There is the following class in the program that is a handler that implements the require interface. And it is called by MediatR.
public class ExampleHandler : IRequestHandler<ExampleRequest, IResult>
{
private readonly GuidService _guidService;
public ExampleHandler(GuidService guidService)
{
_guidService = guidService;
}
public async Task<IResult> Handle(
ExampleRequest request, CancellationToken cancellationToken)
{
await Task.Delay(10, cancellationToken);
return Results.Ok(new
{
message = $"The age was: {request.Age} and the name was: {request.Name}",
requestGuid = request.GuidService.Id,
ctorGuid = _guidService.Id
});
}
}
Question 2a: How does MediatR find this class? It is not passed to anything or registered with anything. Does MediatR scan all classes looking for a match?
Question 2b: And if so, what if there are two matches?
Question 2c: Also if so, is there a way to register handler classes to speed up finding them and avoid duplicate matches?

1. Effectively, yes. The idea is that you're tying individual endpoint operations to a responsible request/response handler, for which a concrete implementation class may implement one or several; the endpoint is abstracted from that responsibility and just needs to know about it's own required input and output pair, resolution is handled by MediatR.
2a. Reflection and assembly scanning. The registration process asks for assemblies to scan, and the MediatR library will locate and attempt to register classes that fulfill its interfaces
https://github.com/jbogard/MediatR/blob/master/src/MediatR/Registration/ServiceRegistrar.cs
MediatR supports Microsoft.Extensions.DependencyInjection.Abstractions
directly. To register various MediatR services and handlers:
services.AddMediatR(cfg =>
cfg.RegisterServicesFromAssemblyContaining()); or with an
assembly:
services.AddMediatR(cfg =>
cfg.RegisterServicesFromAssembly(typeof(Startup).Assembly));
This registers:
IMediator as transient
ISender as transient
IPublisher as transient
IRequestHandler<,> concrete implementations as transient
IRequestHandler<> concrete implementations as transient
INotificationHandler<> concrete implementations as transient
IStreamRequestHandler<> concrete implementations as transient
IRequestPreProcessor<> concrete implementations as transient
IRequestPostProcessor<,> concrete implementations as transient
IRequestExceptionHandler<,,> concrete implementations as transient
IRequestExceptionAction<,>) concrete implementations as transient
This also registers open generic implementations for:
INotificationHandler<>
IRequestPreProcessor<>
IRequestPostProcessor<,>
IRequestExceptionHandler<,,>
IRequestExceptionAction<,>
2b. Which takes precedence depends on how you register them, but MediatR will only resolve one IRequestHandler for a given type. The assembly scanner will register the first located handler and will skip any additional ones it finds. If you manually register multiple, it will use the last registered.
2c. Yes. You do not have to use the automated assembly scanning via the registration extensions to register MediatR; you can manually register the implementations of IMediator, ISender, and IPublisher yourself, and then selectively register all of your various handlers manually into the IoC container.

Related

When to instantiate the repository and which is the lifespan of it?

In DDD, is the application layer who uses the repository to get the data from database, call the methods of the domain and then call the repository to persists the data. Something like that:
public void MyApplicationService()
{
Order myOrder = _orderRepository.Get(1);
myOrder.Update(data);
_orderRepository.Commit();
}
In this example the repository is a class variable that it is instantiate in the constructor of the service, so its life is the life of the class.
But I am wondering if it wouldn't be better to instantiate a repository for each action that I want to do, to have a shorter life, because if not, if I use the class for many actions, the repository will have many entities that perhaps it will not need more.
So I was thinking in a solution like this:
public void MyApplicationService()
{
OrderRepository myOrderRepository = new OrderRepository(_options);
Order myOrder = myOrderRepository.GetOrder(1);
myOrder.Update(data);
myOrderRepository.Commit();
myOrderRepository.Dispose();
}
So a new instance each time I need to do the action.
So in sumary, I would like to know about the differents solutions and the advantages and disadvanges to decide the lifespan of the repository.
Thanks.
The recommended lifespan of the repository is one business transaction.
Your second patch of code is correct in that aspect, however it has one drawback: you have created a strong dependency between the ApplicationService and OrderRepository classes. With your code, you are not able to isolate both class in order to unit test them separately. Also, you need to update the ApplicationService class whenever you change the constructor of the OrderRepository. If OrderRepository requires parameters to construct, then you have to construct them (which implies to reference their type and base types), despite this being an implementation detail of OrderRepository (needed for data persistence store access) and not needed for your application service layer.
For these reasons, most of modern program development rely on a pattern called Dependency Injection (DI). With DI, you specify that your ApplicationService class depends on an instance of the OrderRepository class, or better, an interface IOrderRepository whom the OrderRepository class implements. The dependency is declared by adding a parameter in the ApplicationService constructor:
public interface IOrderRepository : IDisposable
{
Order GetOrder(int id);
void Commit();
}
public class ApplicationService
{
private readonly OrderRepository orderRepository;
public ApplicationService(IOrderRepository orderRepository)
{
this.orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
}
public void Update(int id, string data)
{
Order myOrder = orderRepository.Get(id);
myOrder.Update(data);
orderRepository.Commit();
}
}
Now the DI library is responsible to construct OrderRepository and inject the instance in the ApplicationService class. If OrderRepository has its own dependencies, the library will resolve them first and construct the whole object graph so you don't have to do that yourself. You simply need to tell your DI library what specific implementation you want for each referenced interface. For example in C#:
public IServiceCollection AddServices(IServiceCollection services)
{
return services.AddScoped<IOrderRepository,OrderRepository>();
}
When unit testing your code, you can replace the actual implementation of OrderRepository with a mock object, such as Mock<IOrderRepository> or your own MockOrderRepository implementation. The code under test is then exactly the code in production, all wiring being done by the DI framework.
Most modern DI libraries have support for object lifetime management, including transient (always resolve a new object), singleton (always reuse the same object), or scoped (each scope has a single instance). The latter is what is used to isolate objects instance per business transaction, using a singleton ScopeFactory to create scopes whenever you start a business transaction:
public class UpdateOrderUseCase : UseCase
{
private readonly IScopeFactory scopeFactory;
public UpdateOrderUseCase(IScopeFactory scopeFactory) // redacted
public void UpdateOrder(int id, string data)
{
using var scope = scopeFactory.CreateScope();
var orderRepository = scope.GetService<IOrderRepository>();
var order = orderRepository.Get(id);
order.Update(data);
orderRepository.Commit();
// disposing the scope will also dispose the object graph
}
}
When you implement a REST service, that transaction usually corresponds to one HTTP request. Modern frameworks, such as asp.net core, will automatically create scopes per HTTP request and use that to resolve your dependency graph later in the framework internals. This means you don't even have to handle the ScopeFactory yourself.

Container.GetInstance(Type) when using WcfOperationLifestyle throws ActivationException

I have a WebAPI service using SimpleInjector. I have this set up using AsyncScopedLifestyle for my scoped dependencies, and one of these dependencies is my Entity Framework DataContext. Many things in my service depend on the DataContext, and it is generally injected in to my MediatR handlers using constructor injection - this works well. Separately I have a few areas where I need to create an instance of an object given its type (as a string), so I have created a custom activator class (ResolvingActivator) that is configured with a reference to Container.GetInstance(Type):
In my container bootstrap code:
ResolvingActivator.Configure(container.GetInstance);
I can then create objects by using methods such as:
ResolvingActivator.CreateInstance<T>(typeName)
When I'm using WebAPI, the above is working perfectly.
A further part of the project is a legacy API that uses WCF. I have implemented this as a translation layer, where I translate old message formats to new message formats and then dispatch the messages to the Mediator; I then translate the responses (in new format) back to old format and return those to the caller. Because I need access to the Mediator in my WCF services, I'm injecting this in their constructors, and using the SimpleInjector.Integration.Wcf package to let SimpleInjector's supplied SimpleInjectorServiceHostFactory build instances of the services. I've also created a hybrid lifestyle, so I can use the same container for my both my WebAPI and WCF services:
container.Options.DefaultScopedLifestyle = Lifestyle.CreateHybrid(
new AsyncScopedLifestyle(),
new WcfOperationLifestyle());
This works well for some calls, but when a call ultimately calls my ResolvingActivator class, I get an ActivationException thrown, with the following message:
The DataContext is registered as 'Hybrid Async Scoped / WCF Operation' lifestyle, but the instance is requested outside the context of an active (Hybrid Async Scoped / WCF Operation) scope.
As I only receive this error when making WCF calls, I'm wondering if I have something wrong in my configuration. In a nutshell, this will work:
public class SomeClass
{
private readonly DataContext db;
public SomeClass(DataContext db)
{
this.db = db;
}
public bool SomeMethod() => this.db.Table.Any();
}
But this will not:
public class SomeClass
{
public bool SomeMethod()
{
// Code behind is calling container.GetInstance(typeof(DataContext))
var db = ResolvingActivator.CreateInstance<DataContext>();
return db.Table.Any();
}
}
Any ideas where I'm going wrong?
Edit: here is the stack trace from the ActivationException:
at SimpleInjector.Scope.GetScopelessInstance[TImplementation](ScopedRegistration`1 registration)
at SimpleInjector.Scope.GetInstance[TImplementation](ScopedRegistration`1 registration, Scope scope)
at SimpleInjector.Advanced.Internal.LazyScopedRegistration`1.GetInstance(Scope scope)
at lambda_method(Closure )
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.Container.GetInstance(Type serviceType)
at Service.Core.ResolvingActivator.CreateInstance(Type type) in Service.Core\ResolvingActivator.cs:line 43
at Service.Core.ResolvingActivator.CreateInstance(String typeName) in Service.Core\ResolvingActivator.cs:line 35
at Service.Core.ResolvingActivator.CreateInstance[TService](String typeName) in Service.Core\ResolvingActivator.cs:line 69
With a full stack trace here: https://pastebin.com/0WkyHGKv
After close inspection of the stack trace, I can conclude what's going on: async.
The WcfOperationLifestyle under the covers depends on WCF's OperationContext.Current property, but this property has a thread-affinity and doesn't flow with async operations. This is something that has to be fixed in the integration library for Simple Injector; it simply doesn't support async at the moment.
Instead, wrap a decorator around your handlers that start and end a new async scope. This prevents you from having to use the WcfOperationLifestyle all together. Take a look at the ThreadScopedCommandHandlerProxy<T> implementation here to get an idea how to do this (but use AsyncScopedLifestyle instead).

Controlling lifetime of objects created by factory generated by ToFactory()

I am using the following Ninject related nuget packages in an MVC 5 WebAPI application:
Ninject.MVC5
Ninject.Extensions.Factory
ninject.extensions.conventions
I have a simple repository and a corresponding factory class like so:
public interface ITaskRunner
{
void Run();
}
public interface IRepository<T> where T: class
{
T[] GetAll();
}
public interface IRepositoryFactory<T> where T: class
{
IRepository<T> CreateRepository();
}
I have setup the Ninject bindings using ToFactory() from Ninject.Extensions.Factory like so:
kernel.Bind<ITaskRunner>().To<TaskRunner>().InSingletonScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
kernel.Bind<IRepositoryFactory<Contact>>().ToFactory();
I am using the factory in the following class:
public class TaskRunner : ITaskRunner
{
//MyTask is a simple POCO class(not shown for brevity)
IRepositoryFactory<MyTask> repoFactory = null;
IRepository<MyTask> repo = null;
public TaskRunner(IRepositoryFactory<MyTask> repoFactory)
{
this.repoFactory = repoFactory;
repo = repoFactory.CreateRepository();
}
//implementation elided
}
I am noticing that the call to repoFactory.CreateRepository() always returns the same instance of the factory (dynamic proxy) that Ninject generates.
Question : Is there a way to change/control this behavior and set a "lifetime" such as Transient, PerThread etc. for the instance that "CreateRepository" returns?
In this particular case, tasks might be processed asynchronously on multiple threads and the repository is not thread safe and hence singleton behavior for the instance returned from "CreateRepository" is not desirable.
I'm not sure what you are trying to achieve, but results you are seeing are quite expected because your TaskRunner is bound as Singleton (so constructed once), and you retrieve your repository in the TaskRunner constructor, which again happens once, and so repo is always the same instance. Note this happens regardless of how you bind IRepository and IRepositoryFactory, see Captive Dependency post by Mark Seemann for details http://blog.ploeh.dk/2014/06/02/captive-dependency/.
In fact, if you need to create repo in the constructor, you could just inject IRepository itself. The power of the Factory extension lies in the fact that it allows to resolve instances at runtime, not construction time. For example, if your TaskRunner has Run() method, you can create repository in it, so each task to run can have its own instance.

Register WCF proxy wrapper using Unity

I am trying to consume WCF in my MVC web app. I have implemented the channel factory for instantiating the proxy client.
I am stuck at a point. Here is the code highlight -
I created a proxy base class where i am creating the channel :
public abstract class ServiceProxyBase<T> : IDisposable where T : class
For creating teh proxy wrapper class i have inherited this base class as :
public class ProxyWrapper : ServiceProxyBase<IMyService>,IMyService
Here "IMyService" is the WCf contract.
Now, in the controllers i have added overloaded constructors as :
public class AccountController : Controller
{
private IMyService businessService;
public AccountController(IMyService _businessService)
{
this.businessService = _businessService;
}
}
For injecting dependency I have included unity.mvc4 package.
It works fine when I am using the following code :
container.RegisterType<IMyService, ProxyWrapper>();
This works as long as the ProxyWrapper is inheriting the IMyService interface directly. If i remove the inheritance like
public class ProxyWrapper : ServiceProxyBase<IMyService>
it gives an error while registering type.
I would like to have a way without inherting the contract in the proxy wrapper. I have spent almost a day trying to fix this. But am able to figure out a solution.
Please give your valuable suggestions on this.
If I understand correctly, your application is using a WCF service but the functionality your application needs is limited compared to the functionality that the service offers (it contains more methods than you need). According to the Interface Segregation Principle, "no client should be forced to depend on methods it does not use" and the Dependency Inversion Principle states that clients own the abstraction.
In other words, you should define your own interface that the application should use and define an implementation that wraps (i.e. composition over inheritance) the generated WCF proxy class.
For instance:
public interface IMyApplicationService
{
object GetStuff();
void PutStuff(object instance);
}
public class MyServiceApplicationProxy : IMyApplicationService
{
private readonly ProxyWrapper wcfProxy;
public MyServiceApplicationProxy(ProxyWrapper wcfProxy) {
this.wcfProxy = wcfProxy;
}
public object GetStuff() {
return this.wcfProxy.GetStuff();
}
public void PutStuff(object instance) {
this.wcfProxy.PutStuff(instance);
}
}
To make application development easier, makes your code easier to read, maintain and test.
You might even want to change the methods of your interface to better suit your application needs. Remember: the client defines the interface! So that might mean that you need to do more mapping inside the MyServiceApplicationProxy class to map adapt your core domain to the contract of the external web service. Don't let the external WCF service's contract leak into your core domain.

How to decorate interfaces bound to more than one concrete type with Ninject

So, I have a message bus that instantiates message handlers through Ninject. I'd like to decorate my handlers with cross cutting concerns such as logging, transaction management, etc.
I setup my bindings like so:
kernel.Bind<IMessageHandler<int>>().To<IntHandlerOne>()
.WhenInjectedInto(typeof(HandlerDecorator<>));
kernel.Bind(typeof(IMessageHandler<>)).To(typeof(HandlerDecorator<>));
Which works fantastically whenever I have a single handler of a specific message type. However, when I have more than one handler defined:
kernel.Bind<IMessageHandler<int>>().To<IntHandlerOne>()
.WhenInjectedInto(typeof(HandlerDecorator<>));
kernel.Bind<IMessageHandler<int>>().To<IntHandlerTwo>()
.WhenInjectedInto(typeof(HandlerDecorator<>));
kernel.Bind(typeof(IMessageHandler<>)).To(typeof(HandlerDecorator<>));
Ninject will find and inject the decorator to the message bus, and then attempt unsuccessfully to inject both handlers into the decorator constructor.
public HandlerDecorator(IMessageHandler<T> handler)
You may be thinking, why don't I just modify my decorator to accept the list of handlers? I thought about this, but that defeats the purpose of the handler. I want to be able to easily chain multiple decorators together transparently. Each instance of IMessageHandler<T> should get an entirely new chain of handlers.
I've published an example test library on GitHub that should illustrate what I'm talking about here.
Is there any way to do this in Ninject?
Use
kernel.Bind<IMessageHandler<int>>().To<IntHandlerOne>().WhenParentNamed("One");
kernel.Bind<IMessageHandler<int>>().To<IntHandlerTwo>().WhenParentNamed("Two");
kernel.Bind(typeof(IMessageHandler<>)).To(typeof(HandlerDecorator<>)).Named("One");
kernel.Bind(typeof(IMessageHandler<>)).To(typeof(HandlerDecorator<>)).Named("Two");
Also be aware that most of the Bus Frameworks have some way to do decorations for message handlers. May have a look there first.
You should wrap those handlers in a composite:
public class CompositeMessageHandler<T> : IMessageHandler<T>
{
private readonly IEnumerable<IMessageHandler<T>> handlers;
CompositeMessageHandler(IEnumerable<IMessageHandler<T>> handlers)
{
this.handlers = handlers;
}
public void Handle(T message)
{
foreach (var handler in this.handlers)
{
handler.Handle(message);
}
}
}
This composite can again be injected into your decorator. Or perhaps you should do it the other way around: Wrap each handler with a decorator and wrap those into the composite.
I'm not sure how to register this with Ninject though.