Decorating specific command handlers with unit of work - c#

I am trying to rewrite my app from a service pattern to a command and query pattern (before I move to CQRS). Currently I'm stuck on this blog.
It shows where he moved unit of work commit from the base command into a PostCommitCommandHandlerDecorator, then use Simple Injector to bind them up. The writer also stated that not all commands will require the use of unit of work, which is true in my case because not every command talks to a database but some send emails, etc.
How do I architect my commands and bindings in such a way that only those commands that are required to be wrapped in a unit of work commit will be bound as such by the IoC container?

How do I architect my commands and bindings in such a way that only those commands that are required to be wrapped in a unit of work commit will be bound as such by the IoC container?
First of all, does that really matter that not all handlers use the unit of work? Is it a problem when a unit of work is created, while it isn’t used? Because when there are no performance problems, there’s no need to make your code more complicated.
But let’s assume that it does matter. In that case, the trick is to query the container whether the unit of work is injected somewhere. You can make use of Lazy<T> to get this working. Take a look at the following registration:
Func<IUnitOfWork> uowFactory =
() => new MyUnitOfWork(connectionString);
// Register the factory as Lazy<IUnitOfWork>
container.Register<Lazy<IUnitOfWork>>(
() => new Lazy<IUnitOfWork>(uowFactory),
Lifestyle.Scoped);
// Create a registration that redirects to Lazy<IUnitOfWork>
container.Register<IUnitOfWork>(
() => container.GetInstance<Lazy<IUnitOfWork>>().Value,
Lifestyle.Scoped);
For the rest of the article I assume you're building a web application, but the idea will be the same.
With this registration, when the container resolves an object graph with a component that depends on IUnitOfWork, under the covers it will resolve the Lazy<IUnitOfWork> and get its value. We cache the Lazy<IUnitOfWork> per request, so this allows us to have another component that depends on Lazy<IUnitOfWork> and check its IsValueCreated property to see if the IUnitOfWork was injected anywhere.
Now your decorator could look like this:
public class TransactionCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> decorated;
private readonly Lazy<IUnitOfWork> lazyUnitOfWork;
public TransactionCommandHandlerDecorator(
ICommandHandler<TCommand> decorated,
Lazy<IUnitOfWork> lazyUnitOfWork)
{
this.decorated = decorated;
this.lazyUnitOfWork = lazyUnitOfWork;
}
public void Handle(TCommand command)
{
this.decorated.Handle(command);
if (this.lazyUnitOfWork.IsValueCreated)
{
this.lazyUnitOfWork.Value.SubmitChanges();
}
}
}
Note however that you still don’t know whether the unit of work is actually used or not, but I think it’s safe to assume that the unit of work will be used when it gets injected. You don’t want to inject an unused dependency.
If that doesn’t cut it, and you want to check whether it is created, you will have to inject a proxy unit of work that allows you to check this. For instance:
public class DelayedUnitOfWorkProxy : IUnitOfWork
{
private Lazy<IUnitOfWork> uow;
public DelayedUnitOfWorkProxy(Lazy<IUnitOfWork> uow)
{
this.uow = uow;
}
void IUnitOfwork.SubmitChanges()
{
this.uow.Value.SubmitChanges();
}
// TODO: Implement All other IUnitOfWork methods
}
Your configuration will now look like this:
Func<IUnitOfWork> uowFactory =
() => new MyUnitOfWork(connectionString);
// Register the factory as Lazy<IUnitOfWork>
container.Register<Lazy<IUnitOfWork>>(
() => new Lazy<IUnitOfWork>(uowFactory),
Lifestyle.Scoped);
// Register the proxy that delays the creation of the UoW
container.Register<IUnitOfWork, DelayedUnitOfWorkProxy>(
Lifestyle.Scoped);
When a command or any other dependency needs an IUnitOfWork, they will get the DelayedUnitOfWorkProxy, and it is injected with a Lazy<IUnitOfWork>. So after the object graph is created, the unit of work itself will not be created yet. Only when one of the DelayedUnitOfWorkProxy method is called, such instance is created. The decorator will stay the same.
But even this might not be good enough. It is possible that your MVC controller (assuming you are building an ASP.NET MVC application) depends on a query that uses the unit of work, but the command handler does not. In that case you probably still wouldn't want to commit the unit of work, because the command handler (or one of its dependencies) still doesn't use the unit of work.
In that case what you’re actually trying to do is to isolate the execution of command handlers in their own scope. As if they are running in a different App Domain. You want them to be independent of the web request in which they execute.
In that case you need an hybrid lifestyle. With Simple Injector you can leave all your code and configuration in tact, but switch to an hybrid lifestyle like this:
container.Options.DefaultScopedLifestyle = Lifestyle.CreateHybrid(
() => container.GetCurrentLifetimeScope() != null,
new LifetimeScopeLifestyle(),
new WebRequestLifestyle());
Func<IUnitOfWork> uowFactory =
() => new MyUnitOfWork(connectionString);
// Register the factory as Lazy<IUnitOfWork>
container.Register<Lazy<IUnitOfWork>>(
() => new Lazy<IUnitOfWork>(uowFactory),
Lifestyle.Scoped);
// Register a proxy that depends on Lazy<IUnitOfWork>
container.Register<IUnitOfWork, DelayedUnitOfWorkProxy>(
Lifestyle.Scoped);
An hybrid lifestyle is a composite of two (or more) lifestyles and it contains a predicate delegate that the container will call to check which lifestyle should be applied.
With just this configuration nothing will happen, because the LifetimeScopeLifestyle requires you to explicitly start and stop a new scope. Without a scope the container.GetCurrentLifetimeScope() method will always return null, which means that the hybrid lifestyle will always pick the WebRequestLifestyle.
What you need is to start a new lifetime scope just before you resolve a new command handler. As always, this can be done by defining a decorator:
private sealed class LifetimeScopeCommandHandlerDecorator<T>
: ICommandHandler<T>
{
private readonly Container container;
private readonly Func<ICommandHandler<T>> decorateeFactory;
public LifetimeScopeCommandHandlerDecorator(Container container,
Func<ICommandHandler<T>> decorateeFactory)
{
this.decorateeFactory = decorateeFactory;
this.container = container;
}
public void Handle(T command)
{
using (this.container.BeginLifetimeScope())
{
var decoratee = this.decorateeFactory.Invoke();
decoratee.Handle(command);
}
}
}
You should register this decorator as last decorator (outer most decorator). Instead of depending on an ICommandHandler<T> this decorator depends on an Func<ICommandHandler<T>>. This makes sure that the decorated command handler will only get resolved when the Func<T> delegate is invoked. This postpones the creation and and allows the creation of a lifetime scope first.
Since this decorator depends on two singletons (both the container and the Func<T> are singletons), the decorator itself can also be registered as singleton. This is what your configuration might look like:
// Batch register all command handlers
container.Register(
typeof(ICommandHandler<>),
typeof(ICommandHandler<>).Assembly);
// Register one or more decorators
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>));
// The the lifetime scope decorator last (as singleton).
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(LifetimeScopeCommandHandlerDecorator<>),
Lifestyle.Singleton);
This will effectively isolate the unit of work used by commands from any unit of work that is created outside the context of a command handler within the rest of the request.

There is a simple way to achieve what you are asking. There are overloaded versions of the RegisterDecorator extension method that accept a Predicate which, in combination with a marker interface, can be used to selectively apply a decorator.
Here's an example in code:
public interface ICommandHandler<T> where T : class { }
public interface IDontUseUnitOfWork { }
public class MyCommand { }
public class MyCommandHandler :
ICommandHandler<MyCommand>, IDontUseUnitOfWork { }
public sealed class UnitOfWorkCommandDecorator<T> :
ICommandHandler<T> where T : class
{
public UnitOfWorkCommandDecorator(ICommandHandler<T> decorated) { }
}
And the registration to apply the UnitOfWorkCommandDecorator to command handlers except those that are tagged with the IDontUseUnitOfWork interface:
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(UnitOfWorkCommandDecorator<>),
x => !typeof(IDontUseUnitOfWork).IsAssignableFrom(x.ImplementationType));
This predicate feature is very useful and well worth getting to grips with.

Related

Injecting dependencies with runtime dependencies

I'm building an application that performs actions initiated by a user and one particular class has dependencies on things I can wire up in DI such as an ILogger instance as well as an HttpClient in addition to runtime arguments that identify the user and the instance of the action (mostly to be used while logging to help with debugging).
The trouble I have is that I'm not entirely sure how to inject this class into the other classes that need it as a result of the runtime dependencies.
Here's a simplified example of one of my classes:
public class Dependency : IDependency
{
private readonly HttpClient httpClient;
private readonly ILogger<Dependency> logger;
private readonly RuntimeDeps runtimeDeps
public Dependency(
ILogger<Dependency> logger,
HttpClient httpClient,
RuntimeDeps runtimeDeps)
{
// set private fields
}
public Result DoStuff()
{
// use Http client to talk to external API
// something fails so log the failure and some helpful info
logger.log($"{runtimeDeps.InstanceId} failed. " +
"Initiated by {runtimeDeps.UserName}");
}
}
This feels like it requires a factory to create but then is it best to request the HttpClient and Logger in the factory method or declare it as a dependency of the factory? If the latter, I presume the factory would have to be registered as a transient or as a scoped resource since registering it as a singleton would result in a captive dependency (I think).
Any suggestions on redesigns are also welcome if this is a symptom of a poor design. I'd love to implement Mark Seeman's Pure DI to get some more assistance from the compiler but I don't know if that's possible in Azure functions.
A transient factory with the transient dependencies injected into the constructor and the runtime dependencies as parameters of the Create method will work fine.
DI is baked into the Azure Functions library in the sense that parameters are injected into the trigger methods, but beyond these you should be able to use Pure DI to manage your own dependencies by calling into some composition root helper class from the trigger function which knows how to build your dependency graph in a pure manner.
Instead of requiring runtime data during the construction of a component, it's better to let runtime data flow through method calls on an initialized object graph by either:
passing runtime data through method calls of the API or
retrieving runtime data from specific abstractions that allow resolving runtime data.
I formalized this in 2015 in this blog post, which I referred to in the comments.
After reading your additional comments, I came to the conclusion that in your case option 2 is most suited, as the data you are sending is likely an implementation detail to the component, and should not be part of the public API.
In that case, you can redesign your component as follows:
public class Dependency : IDependency
{
public Dependency(
ILogger<Dependency> logger,
HttpClient httpClient,
IRuntimeDepsProvider provider) ...
public Result DoStuff()
{
// use Http client to talk to external API
// something fails so log the failure and some helpful info
logger.log($"{provider.InstanceId} failed. " +
$"Initiated by {provider.UserName}");
}
}
IRuntimeDepsProvider is an abstraction that hides the retrieval and storage of runtime data. This gives you the ability to postpone the decision to either use a Closure Composition Model or an Ambient Composition Model until the Last Responsible Moment.
Using the IRuntimeDepsProvider abstraction, you can chose to set the incoming runtime values after the object graph is constructed. For instance:
public class MyFunction
{
// Notice the different abstraction here
public MyFunction(
IRuntimeDepsInitializer initializer,
IHandler<Something> handler) ...
public void TheFunction(Guid instanceId, string userName, Something cmd)
{
// Setting the runtime data *after* the object graph is constructed,
initializer.SetData(instanceId, userName);
// but before the graph's public methods are invoked.
handler.Handle(cmd);
}
}
Here, a second abstraction is introduced, namely IRuntimeDepsInitializer. Now you can have one class implementing both interfaces:
public class RuntimeDepsStorage : IRuntimeDepsInitializer, IRuntimeDepsProvider
{
public Guid InstanceId { get; private set; }
public string UserName { get; private set; }
public void SetData(Guid id, string name)
{
InstanceId = id;
UserName = name;
}
}
TIP: Instead of using two interfaces, you can also use only IRuntimeDepsProvider and let MyFunction depend on the concrete RuntimeDepsStorage. Which solution is best depends on the context.
Now the main trick here is to make sure that RuntimeDepsStorage becomes a Scoped dependency, because you want to reuse it throughout a request, but not shared by multiple requests.
When applying Pure DI, this would look like this:
var storage = new RuntimeDepsStorage();
new MyFuncion(
initializer: storage,
handler: new SomethingHandler(
stuffDoer: new Dependency(
httpClient: client, // Did you notice this is a runtime dep as well?
logger: new Logger<Dependency>(),
provider: storage)))
If, on the other hand, you would be using MS.DI as your DI Container, registration would be similar to the following:
services.AddScoped(_ => new RuntimeDepsStorage());
services.AddScoped<IRuntimeDepsProvider>(
c => c.GetRequiredService<RuntimeDepsStorage>());
services.AddScoped<IRuntimeDepsInitializer>(
c => c.GetRequiredService<RuntimeDepsStorage>());
// etc, your usual registrations here

Castle Windsor intercept method call from within the class

We have components registrations in Castle Windsor container like so
void RegisterComponent<TInterface, TImplementation>() {
var component = Component.For<TInterface>().ImplementedBy<TImplementation>();
component.Interceptors<SomeInterceptor>();
container.Register(component);
}
However we got to the problem that when we do a method call from within the class it does not get intercepted. For example we have component like
ServiceA : IService {
public void MethodA1() {
// do some stuff
}
public void MethodA2() {
MethodA1();
}
}
And if we call MethodA2 or MethodA1 methods from some other class it is intercepted, but MethodA1 apparently not intercepted when called from MethodA2 since the call is from within the class.
We have found similar case with the solution Castle Dynamic Proxy not intercepting method calls when invoked from within the class
However the solution features component and proxy creation using new operator which is not suitable in our case since we are using container. Can we use this solution with component registration like above? Or are there other approaches to solve the problem?
For interception to work on MethodA1 when invoked from MethodA2 you need to be using inheritance based interception (it's because you are using this reference to make the invocation).
To make inheritance based interception possible first you need to make MethodA1 and MethodA2 virtual.
Then you can make container registration like this:
container.Register(Component.For<ServiceA>().Interceptors<SomeInterceptor>());
container.Register(Component.For<IService>().UsingFactoryMethod(c => c.Resolve<ServiceA>()));
First register your service as itself applying interceptors (this will add inheritance based interception over the service). Then you can register the interface which will use service registered earlier.
Change your registration to the following and Windsor should switch to class proxies - i.e. using inheritance for interception, instead of composition.
void RegisterComponent<TInterface, TImplementation>() {
container.Register(Component.For<TInterface,TImplementation>().ImplementedBy<TImplementation>().Interceptors<SomeInterceptor>());
}
We use CreateClassProxy method to create the proxy for the service as it was proposed in an answer to the question Castle Dynamic Proxy not intercepting method calls when invoked from within the class.
Then we register the obtained proxy as an implementation for the interface.
So our custom RegisterComponent method looks like this
private void RegisterComponent<TInterface, TImplementation>()
where TInterface : class
where TImplementation : class, TInterface
{
var proxyType = new ProxyGenerator().CreateClassProxy<TImplementation>().GetType();
Container.Register(Component.For<TInterface>().ImplementedBy(proxyType));
}
The full component registration is
Container = new WindsorContainer();
Container.Kernel.Resolver.AddSubResolver(new CollectionResolver(Container.Kernel));
// Interceptor
Container.Register(Component.For<IInterceptor>().ImplementedBy<SomeInterceptor>().LifestyleTransient());
// Component registrations
RegisterComponent<ISomeService, SomeService>();
And, of course, all methods you need to intercept should be virtual since inheritance based proxy is used.
However a drawback of this solution is that you could not use constructor injection when creating a proxy object.
Notice that you are creating "dummy" proxy object with new operator only to get a type of the proxy. Therefore you are unable to use constructor injection only when constructing a dummy proxy, but when you resolve your service via container, injection would work just fine. So this drawback is critical only for components with construction logic being more complex than just assigment of dependencies. If you need only dependency assigments you can try to resolve all dependencies from container manually before creating dummy proxy
private object[] ResolveConstructorParameters<TType>()
{
return typeof(TType).GetConstructors()
.Single(c => c.IsPublic)
.GetParameters()
.Select(p => _container.Resolve(p.ParameterType))
.ToArray();
}
and then RegisterComponent would become
private void RegisterComponent<TInterface, TImplementation>()
where TInterface : class
where TImplementation : class, TInterface
{
var constructorParameters = ResolveConstructorParameters<TImplementation>();
var proxyType = new ProxyGenerator().CreateClassProxy(typeof(TImplementation), constructorParameters).GetType();
_container.Register(Component.For<TInterface>().ImplementedBy(proxyType));
}
You can also just fill arguments with null.
#NikolayKondratyev I've looked into https://github.com/castleproject/Windsor/blob/master/src/Castle.Windsor/Windsor/Proxy/DefaultProxyFactory.cs#L110
and I've done the registration the easy way:
container.Register(Classes.FromThisAssembly().BasedOn(typeof(IRepositoryBase<,>))
.WithServiceAllInterfaces().WithServiceSelf()
.LifestyleTransient());
Note .WithServiceSelf() call, this actually switches class-based proxying
I know this is an old thread, but I just came across it while getting Castle interceptors working in Blazor WASM (which they actually do, but beware...Mono can't seem to support proxying any class that has any generic methods...).
Anyway, to get around this issue in my case, I simply injected the container into my class, and in the method that needed to call a "sibling method" via this I simply resolved a fresh instance of my interface and called the method on that. It won't work for scenarios with shared context/transient states, but the interceptor indeed does its thing.
In Blazor's client WASM app's Program.cs:
public static async Task Main(string[] args)
{
WebAssemblyHostBuilder builder = WebAssemblyHostBuilder.CreateDefault(args);
...
builder.ConfigureContainer<IWindsorContainer>(new WindsorServiceProviderFactory(), container =>
{
container.Register(Component.For<IInterceptor>()
.ImplementedBy<BlazorInterceptor>()
.Named("BlazorInterceptor").LifestyleTransient());
});
...
builder.Services.AddScoped<IService, Service>();
...
await builder.Build().RunAsync();
}
Example service and interface implementation:
public Interface IService
{
MethodA(int arg);
MethodB(int arg);
}
[Interceptor("BlazorInterceptor")]
public class Service : IService
{
private readonly IServiceProvider _container;
public Service(IServiceProvider container)
{
this._container = container;
}
public MethodA(int arg)
{
IService service = this._container.GetRequiredService<IService>();
service.MethodB(arg);
}
public MethodB(int arg)
{
//should be intercepted...just in a different instance of the service unless you're using singletons...
}
}
Pros: Doesn't require virtualizing methods or complicating your DI configuration.
Cons: Kind of gross (useful for stateless repositories, but would probably give something like EF a heart attack).

Use of ResolveUnregisteredType causes Torn Lifestyle warning in Simple Injector v3.0.3

I use a self-made "external" library to get some basic infrastructure in place when creating new web-applications. I recently made some changes to how my repositories work and came across this warning from Simple Injector Diagnostic Warnings:
SimpleInjector.DiagnosticVerificationException : The configuration is
invalid. The following diagnostic warnings were reported:
-[Torn Lifestyle] The registration for IUnitOfWork maps to the same implementation and lifestyle as the registrations for IUnitOfWork,
IUnitOfWork, IUnitOfWork and IUnitOfWork do. They all map to
EmptyUnitOfWork (Singleton). This will cause each registration to
resolve to a different instance: each registration will have its own
instance. See the Error property for detailed information about the
warnings. Please see https://simpleinjector.org/diagnostics how to fix
problems and how to suppress individual warnings.
The core assembly of my library has an empty implementation of IUnitOfWork called EmptyUnitOfWork which is just a simple no-op class:
internal sealed class EmptyUnitOfWork : IUnitOfWork
{
public void SaveChanges()
{
// Do nothing
}
}
This class is then registered in the container when there is no other unit of work avaliable. I do this by using the container.ResolveUnregisteredType(...) like so:
// Register an EmptyUnitOfWork to be returned when a IUnitOfWork is requested:
container.ResolveUnregisteredType += (sender, e) =>
{
if (e.UnregisteredServiceType == typeof(IUnitOfWork))
{
// Register the instance as singleton.
var registration = Lifestyle.Singleton.CreateRegistration<IUnitOfWork, EmptyUnitOfWork>(container);
e.Register(registration);
}
};
First time I've used above method - but works fine with this test:
[Fact]
public void RegistersEmptyUnitOfWork_AsSingleton_WhenIUnitOfWorkIsNotRegisted()
{
var instance = _container.GetInstance<IUnitOfWork>();
var registration = _container.GetRegistration(typeof (IUnitOfWork));
Assert.NotNull(instance);
Assert.IsType<EmptyUnitOfWork>(instance);
Assert.Equal(Lifestyle.Singleton, registration.Lifestyle);
}
Now for the fun part, I have an extension method in a supporting library which registers an EntityFramework IUnitOfWork if my application needs one:
public static void RegisterEntityFramework<TContext>(this Container container) where TContext : DbContext
{
if (container == null)
throw new ArgumentNullException(nameof(container));
var lifestyle = Lifestyle.CreateHybrid(() =>
HttpContext.Current != null,
new WebRequestLifestyle(),
new LifetimeScopeLifestyle()
);
container.Register<DbContext, TContext>(lifestyle);
container.Register<IUnitOfWork, EntityFrameworkUnitOfWork>(lifestyle);
container.Register(typeof (IRepository<>), typeof (EntityFrameworkRepository<>), lifestyle);
}
But somehow this throws the warning from Simple Injector - but I just injected the EntityFrameworkUnitOfWork so the EmptyUnitOfWork should not be triggered?
The reason for this design is that I have a CommandTransactionDecorator in my core library which uses the IUnitOfWork to save changes. I just want to have an empty one if a IUnitOfWork is not required by the application.
For reference this is the decorator:
internal sealed class CommandTransactionDecorator<TCommand> : IHandleCommand<TCommand> where TCommand : ICommand
{
private readonly IUnitOfWork _unitOfWork;
private readonly Func<IHandleCommand<TCommand>> _handlerFactory;
public CommandTransactionDecorator(IUnitOfWork unitOfWork, Func<IHandleCommand<TCommand>> handlerFactory)
{
_unitOfWork = unitOfWork;
_handlerFactory = handlerFactory;
}
public void Handle(TCommand command)
{
_handlerFactory().Handle(command);
_unitOfWork.SaveChanges();
}
}
UPDATE
It seems like this is the registration that makes the warning:
var registration = Lifestyle.Singleton.CreateRegistration<IUnitOfWork, EmptyUnitOfWork>(container);
e.Register(registration);
Changing it to e.Register(() => new EmptyUnitOfWork()); makes the warning go away, but then the lifestyle is not singleton?
What you are seeing is that ResolveUnregisteredType is called multiple times. This causes multiple singleton registrations for the same type to be made. Each registration gets its own instance. This will result in an application that consists of multiple instances of that type, which is usually not what you want to happen when you register a type as singleton. Since your EmptyUnitOfWork doesn't have any behavior, there is probably no problem, but Simple Injector can obviously not guess that this is the case, so it throws an exception.
What you are experiencing however is a breaking change / bug that was introduced in Simple Injector v3. In Simple Injector v1 and v2 the resulting registration of a ResolveUnregisteredType was cached; which meant that a call to Verify() would trigger your custom delegate just once. In Simple Injector v3.0 however, the resulting registration isn't cached anymore. This was an oversight, that has slipped through. The idea was to make ResolveUnregisteredType context aware. To be context aware, caching was not an option anymore. So caching was removed, but we eventually decided not to make ResolveUnregisteredType context aware, while we forgot to add the caching again.
The funny thing of this accidental behavior however is, that it expose a bug in your code. This bug already existed even when you used v2, but v3 now (accidentally) slaps you in the face with it. With v2, the correctness of your registration depended on the use of the Verify() method. Verify() builds all object graphs on a single thread. Without the use of Verify() however, the object graphs are compiled lazily and in case you are running a multi-threaded application, multiple threads can simultaneously call ResolveUnregisteredType; Simple Injector never locked ResolveUnregisteredType and this is documented.
So the result of this is that without a call to Verify() you could still end up in multiple registrations of that specific component, which of course again could lead to really ugly hard to find problems, that usually only appear once in a way in production.
This is how you should actually write that registration:
Lazy<Registration> registration = new Lazy<Registration>(() =>
Lifestyle.Singleton.CreateRegistration<IUnitOfWork, EmptyUnitOfWork>(container));
container.ResolveUnregisteredType += (sender, e) => {
if (e.UnregisteredServiceType == typeof(IUnitOfWork)) {
e.Register(registration.Value);
}
};
With Simple Injector v3 however, you hardly ever have to use the ResolveUnregisteredType event anymore. You can do make the following registration instead:
container.RegisterConditional<IUnitOfWork, EntityFrameworkUnitOfWork>(Lifestyle.Scoped,
c => true);
// NOTE: This registration must be made second
container.RegisterConditional<IUnitOfWork, EmptyUnitOfWork>(Lifestyle.Singleton,
c => !c.Handled);
This solves the problem of having to think about multi-threading completely. Here we make two conditional registrations, where the first is always applied (using the predicate c => true). You might be tempted to make the first registration unconditional using Register<IUnitOfWork, EFUoW>(), but that won't work, because Simple Injector will detect that the second registration can never be applied and an exception will be thrown. So the use of the c => true predicate suppresses this detection. I wouldn't usually advice such construct, because it blinds Simple Injector. In your case however it seems reasonable, because both registrations are made at different moment.
I now will have to think about whether or not I want to change this behavior in v3 and do caching. Advantage of caching is that it can improve performance, but the downside is that it hides bugs.

Get the container instance for Simple Injector

I am using Simple Injector with a ASP.NET MVC project. I added the SimpleInjector.Integration.Web.Mvc nuget package. This adds SimpleInjectorInitializer class in App_Start folder and initializes the DI. The code looks something like
public static void Initialize()
{
// Did you know the container can diagnose your configuration?
// Go to: https://simpleinjector.org/diagnostics
var container = new Container();
//Container configuration code
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
}
This configures the DI for the MVC controller correctly.
My question is, if I want to get the instance of the container in any of the controller\class to resolve some dependency manually how can I do it.
I have earlier worked on AutoFac and it has a dependency interface IComponentContext which can be injected into any class that needs to do any resolution manually.
Update:
Here is a scenario. My controller uses a service who initialization depends upon the input parameter passed in the controller method and hence the dependency cannot be instantiated during construction time.
I understand that this is somewhat an anti pattern for DI, but it is requirement at few places and hence injecting the DI container is next best thing. Simple Injector samples should use of static variable to share the container which i want to avoid and also it is not possible by the way SimpleInjectorInitializer works.
Except for any code that is part of the startup path of the application, no code should depend directly on the container (or a container abstraction, container facade, etc). This pattern is called Service Locator and Mark Seemann has a good explanation why this is a bad idea.
So components (such as Controllers) should not depend on the container directly, since this hides the used dependencies and makes classes harder to test. Furthermore your code starts to depend on an external framework (making it harder to change) or depending on an abstraction it doesn't need to know about.
My controller uses a service who initialization depends upon the input
parameter passed in the controller method and hence the dependency
cannot be instantiated during construction time
There's a general pattern for this problem: the abstract factory design pattern. The factory pattern allows you to delay the creation of types and allows you to pass in extra runtime parameters for the construction of a certain type. When you do this, your controller doesn't have to depend on Container and it prevents you from having to pass in a constructed container in your unit tests (DI frameworks should in general not be used in your unit test projects).
Do note however that letting your components require runtime data during creation is a code smell. Prevent doing that.
You might think that by doing this we are just moving the problem to the factory implementation. Although we are moving the dependency on the container into the factory implementation, we are in fact solving the problem because the factory implementation will be part of the application's Composition Root, which allows the application code itself oblivious to any DI framework.
So this is how I advice you to structure your code:
// Definition of the factory in the UI or BL layer
public interface ISomeServiceFactory
{
ISomeService Create(int inputParameter);
}
// Controller depending on that factory:
public class MyController : Controller
{
private readonly ISomeServiceFactory factory;
public MyController(ISomeServiceFactory factory)
{
this.factory = factory;
}
public ActionResult Index(int value)
{
// here we use that factory
var service = this.factory.Create(value);
}
}
In your composition root (the start up path) we define the factory implementation and the registration for it:
private class SomeServiceFactory : ISomeServiceFactory
{
private readonly Container container;
// Here we depend on Container, which is fine, since
// we're inside the composition root. The rest of the
// application knows nothing about a DI framework.
public SomeServiceFactory(Container container)
{
this.container = container;
}
public ISomeService Create(int inputParameter)
{
// Do what ever we need to do here. For instance:
if (inputParameter == 0)
return this.container.GetInstance<Service1>();
else
return this.container.GetInstance<Service2>();
}
}
public static void Initialize()
{
var container = new Container();
container.RegisterSingle<ISomeServiceFactory, SomeServiceFactory>();
}
Upon creation, the Container registers itself (using the call RegisterSingle<Container>(this)) so you can always inject the container into any component. That's similar to injecting the IComponentContext when working with Autofac. But the same holds for Autofac, Simple Injector, and any other container: you don't want to inject your container into components that are located outside the composition root (and there hardly ever is a reason for it).

How to do open generic decorator chaining with unity + UnityAutoRegistration

Went off on an interesting tangent today after reading this article on command handler decoration. I wanted to see if I could implement the pattern using Unity instead of SimpleInjector, and so far it is proving extremely difficult.
The first thing I had to do was install UnityAutoRegistration to resolve the open generic ICommandHandler<TCommand> interface. Current solution for that aspect is as follows:
Container = new UnityContainer().LoadConfiguration();
Container.ConfigureAutoRegistration()
.ExcludeSystemAssemblies()
.Include(type => type.ImplementsOpenGeneric(typeof(ICommandHandler<>)),
(t, c) => c.RegisterType(typeof(ICommandHandler<>), t)
)
.ApplyAutoRegistration()
;
This works for the first part, resolving any single ICommandHandler<TCommand>. What's proven frustrating so far is implementing a decoration handler. As soon as I add a second ICommandHandler<TCommand> as a decorator, Unity throws a StackOverflowException. I don't know enough about Unity internals, but I'm guessing this is because it can't figure out which instance to resolve to -- the command handler, or the command handler decorator -- since both implement the ICommandHandler<TCommand> interface.
Googling around led me first to this article, which explains how to do it in what I would consider a brute force method. I also found these related pages but none is a complete solution to my problem (and I am too ignorant to figure it out for myself).
I then found this article, which seems to address my same concerns. However beefy's solution does not account for dealing with open generics. Currently most of our dependencies are loaded from a unity section in the .config file, so I don't want to write a ton of compiled code for each handler or decorator. It seems like having some kind of UnityContainerExtension and DecoratorBuildStrategy is the right way to go, but I can't figure it out. I have been playing with beefy's code for a little while now, and am completely stuck. My attempts to modify his code to account for generics has led to BadImageFormatExceptions (An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)).
I like the idea of doing this to implement the decorator chaining, because it's short, and there is only 1 line per concern:
var container = new Container();
// Go look in all assemblies and register all implementations
// of ICommandHandler<T> by their closed interface:
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
AppDomain.CurrentDomain.GetAssemblies());
// Decorate each returned ICommandHandler<T> object with an
// TransactionCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>));
// Decorate each returned ICommandHandler<T> object with an
// DeadlockRetryCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(DeadlockRetryCommandHandlerDecorator<>));
...but I don't want to change my container from Unity to Simple Injector if I don't have to.
SO my question is how could I go about implementing open generic decorator chaining using unity (plus UnityAutoRegistration)?
This would be the equivalent in Unity:
// Go look in all assemblies and register all implementa-
// tions of ICommandHandler<T> by their closed interface:
var container = new UnityContainer();
var handlerRegistrations =
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from implementation in assembly.GetExportedTypes()
where !implementation.IsAbstract
where !implementation.ContainsGenericParameters
let services =
from iface in implementation.GetInterfaces()
where iface.IsGenericType
where iface.GetGenericTypeDefinition() ==
typeof(ICommandHandler<>)
select iface
from service in services
select new { service, implementation };
foreach (var registration in handlerRegistrations)
{
container.RegisterType(registration.service,
registration.implementation, "Inner1");
}
// Decorate each returned ICommandHandler<T> object with an
// TransactionCommandHandlerDecorator<T>.
container.RegisterType(typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>),
"Inner2",
InjectionConstructor(new ResolvedParameter(
typeof(ICommandHandler<>), "Inner1")));
// Decorate each returned ICommandHandler<T> object with an
// DeadlockRetryCommandHandlerDecorator<T>.
container.RegisterType(typeof(ICommandHandler<>),
typeof(DeadlockRetryCommandHandlerDecorator<>),
InjectionConstructor(new ResolvedParameter(
typeof(ICommandHandler<>), "Inner2")));
I hope I understand the problem correctly and I was curious to try and get this to work and I'm by no means an expert on Unity but I was thinking of a solution that is a little easier to implement and would also be easier to do with a different container. It would seem like the only way to support the open generic as well as the other types is to have 2 separate containers (1 for the open generic) and one for your command handlers, this might not be the best way but it worked with Unity and I'm assuming will also be easier with others.
So I came up with this:
I created the containers as follows (you can use your convention approach still im sure for the handler container)
var container = new UnityContainer();
var container2 = new UnityContainer();
container2.RegisterType(typeof(ICommandHandler<QueryCommand>),
typeof(QueryCommandHandler));
container.RegisterInstance("Handlers", container2);
container.RegisterInstance(container);
container.RegisterType(typeof(ICommandHandler<>),
typeof(DecoratedHandler<>));
You see container 2 containing the Handlers as a named instance.
Then I just created a Generic base decorator class as per the requirement of the pattern:
public class DecoratorCommandHandler<TCommand>
: ICommandHandler<TCommand>
{
private ICommandHandler<TCommand> inner;
public DecoratorCommandHandler(
ICommandHandler<TCommand> inner)
{
this.inner = inner;
}
public virtual void Handle(TCommand command)
{
this.inner.Handle(command);
}
}
Second I created another Generic Handler that would wrap all the Decorations you want to do for your solution, here you will add decorating for TryCatch/Caching/Transactions or whatever else you want to apply to each command handler:
public class DecoratedHandler<TCommand>
: DecoratorCommandHandler<TCommand>
{
public DecoratedHandler(UnityContainer container)
: base(BuildInner(container))
{
}
private static ICommandHandler<TCommand> BuildInner(
UnityContainer container)
{
var handlerContainer =
container.Resolve<UnityContainer>("Handlers");
var commandHandler =
handlerContainer.Resolve<ICommandHandler<TCommand>>();
return new TryCatchCommandHandler<TCommand>(commandHandler);
}
}
You will notice that the first inner resolves the actual command handler as per the one you requested like QueryCommandHandler, UpdateCommandHandler, ExecuteCommandHandler or whatever one dealing with specifics. And then gets wrapped with all the decorators you want common to all of them.
Then I was able to resolve the correct handler, decorated in the correct way:
ICommandHandler<QueryCommand> handler =
container.Resolve<ICommandHandler<QueryCommand>>();
var cmd = new QueryCommand();
handler.Handle(cmd);
Hope this helps

Categories

Resources