StructureMap - Inject Conditional Class - conditional-statements

I have 1 interface named IProcessor having multiple implementations like ABCProcessor, PQRProcessor.
I want to make use of specific processor based on external parameters. How can I achive the same using StructureMap.
I am looking at named instances for the same.

You could use a factory pattern:
public interface IProcessorFactory
{
IProcessor Create(int dropDownValue);
}
public class ProcessorFactory : IProcessorFactory
{
private readonly IContainer _container;
public ProcessorFactory(IContainer container)
{
_container = container;
}
public IProcessor Create()
{
if(//your condition)
return _container.GetInstance<ABCProcessor>();
_container.GetInstance<PQRProcessor>();
}
}
(or simply inject the required dependencies instead of the container)
and then simply
private readonly IProcessorFactory _processorFactory;
public MvcController(IProcessorFactory processorFactory)
{
_processorFactory = processorFactory;
}
public void Method()
{
var processor = _processorFactory.Create();
}

The best solution to your problem is to hide the knowledge of the existence of multiple implementations and the selection between them from the consumer by implementing a proxy implementation for IProcessor:
public sealed ProxyProcessor : IProcessor
{
private readonly ABCProcessor abc;
private readonly PQRProcessor pqr;
private readonly IProcessorConfig config;
public ProxyProcessor(ABCProcessor abc, PQRProcessor pqr, IProcessorConfig config) {
this.abc = abc;
this.pqr = pqr;
this.config = config;
}
// Implement IProcessor methods to forward to the CurrentProcessor.
public void Process() => CurrentProcessor.Process();
private IProcessor CurrentProcessor => config.ProcessorType == "ABC" ? abc : pqr;
}
By doing this you can delegate to the correct implementation at runtime while the consumer stays oblivious to the fact that you make a decision at runtime about this. Now instead of injecting either an ABCProcessor or PQRProcessor into the consumers, you now inject a ProxyProcessor into the consumers. For instance, this is how the object graph for the ProxyProcessor could look like:
IProcessor processor =
new ProxyProcessor(
abc: new ABCProcessor(),
pqr: new PQRProcessor(),
config: new SqlProcessorConfig("constr"));
Note that this solution has several benefits over the use of a factory, such as:
It prevents having to make any changes to the consumers; the consumers stay oblivious.
It prevents introducing unneeded complexity into the consumers; with the factory approach, consumers have to deal with with an extra dependency. This complicates code and tests.
It causes object graphs to be constructed in a delayed fashion, which complicates verification of object graphs.
Please read this article if you want to know more about why factories hardly ever are the right abstraction.

Related

Why WebApplicationFactory is saving state from previous builds?

I will try to show my problem with a sample code easier to understand.
I have used WebApplicationFactory to develop my acceptance tests. Let's say that I have the typical minimal Program.cs with the following line to register one of my modules:
builder.Services.RegisterModule<StartupRegistrationModule>(builder.Configuration, builder.Environment);
And this module is declared like this:
internal sealed class StartupRegistrationModule : IServiceRegistrationModule
{
public static Dictionary<string, string> _dictionary = new();
public void Register(IServiceCollection services, IConfiguration configuration, IHostEnvironment hostEnvironment)
{
// Lot of modules being registered
_dictionary.Add("key", "value");
}
}
One of my tests file is like this:
public sealed class MyTests : AcceptanceTestBase
{
[Fact]
public void Test1()
{
// arrange
// act
// assert
}
[Fact]
public void Test2()
{
// arrange
// act
// assert
}
[Fact]
public void Test3()
{
// arrange
// act
// assert
}
}
And AcceptanceTestBase is:
public abstract class AcceptanceTestBase : IDisposable
{
protected HttpClient _httpClient;
protected WebApplicationFactory<Program> _webApplicationFactory;
public AcceptanceTestBase()
{
_webApplicationFactory = new WebApplicationFactory<Program>()
.WithWebHostBuilder(builder =>
{
// ... Configure test services
});
_httpClient = _webApplicationFactory.CreateClient();
}
public void Dispose()
{
_httpClient.Dispose();
_webApplicationFactory.Dispose();
}
}
If I try to execute all these tests my tests will fail in the second test run because the WebApplicationFactory is trying to build again the Application but it already has the key in the dictionary and it will fail. See the image for more understanding on the problem.
So my question is, how can I build the application in different scopes to do not share this dictionary state?
Thanks :)
Update:
The real static dictionary is saved behind this nuget package that keeps the track of all my circuit breaker policies state. I do not actually need even the HttpClients for my tests but did not find a way to remove them and not load this. I tried removing all the HttpClients to see if it also removes their dependencies, but it does not seem to make the trick.
It is because you are using:
internal sealed class StartupRegistrationModule : IServiceRegistrationModule
{
/// .. static here
public static Dictionary<string, string> _dictionary = new();
public void Register(IServiceCollection services, IConfiguration configuration, IHostEnvironment hostEnvironment)
{
// Lot of modules being registered
_dictionary.Add("key", "value");
}
}
The static Dictionary is shared over all your tests because they run in the same process.
Each test starts a new (Test-)WebHost but the dictionary remains untouched.
My proposal is to not use statics anywhere in DI context to prevent such hidden traps.
I don't know the purpose of your Dictionary here but maybe you can extract this to a singleton registration which you can replace in your (Test.)WebHost on each new test / startup?

Spring Data Redis global TTL for all entities

I need to set global TTL to each entity I have and it should be configurable in one place.
There is an opportunity to do this via #RedisHash annotation:
#RedisHash(value = "persons",timeToLive = 100)
public class Person{
...
}
or I can have a field
public class Person{
#TimeToLeave
Long ttl;
}
but in this case I can't change it in one place and it's not really comfortable
to maintain it.
I have a property in applicaiton.properties:
app.redis.ttl=100
and it will be awesome to have an opportunity to change it on property level.
You can configure settings by creating a subclass of KeyspaceConfiguration and configuring #EnableRedisRepositories. There's no property-based configuration for global TTL.
#EnableRedisRepositories(keyspaceConfiguration = MyKeyspaceConfiguration.class)
public class MyConfig {
}
public class MyKeyspaceConfiguration extends KeyspaceConfiguration {
#Override
public boolean hasSettingsFor(Class<?> type) {
return true;
}
#Override
public KeyspaceSettings getKeyspaceSettings(Class<?> type) {
KeyspaceSettings keyspaceSettings = new KeyspaceSettings(type, "my-keyspace");
keyspaceSettings.setTimeToLive(3600L);
return keyspaceSettings;
}
}
Deriving from KeyspaceConfiguration is intended to provide Iterable<KeyspaceSettings> initialConfiguration() in the first place but since you want to apply that settings to all classes, the in-place creation of KeyspaceSettings makes more sense.
You also might want to cache the KeyspaceSettings to not create instances all over so Java 8's Map.computeIfAbsent(…) would be a good fit.

Simple Injector Property Injection

How do you perform property injection with Simple Injector.
The with Ninject you do is as per bellow:
[Inject]
public IUnitOfWork UnitOfWork { get; set; }
How can I do the equivalent to this with Simple Injector. I tried finding a solution online but had no luck.
Why do I want to use Property Injection?
I want to use property injection to set up unit of work in my base controller so that it will create a new unit of work OnActionExecuting and commit the changes OnResultExecuted. It also means I don't have to pass in the UoW with each new controller I create through the constructor.
Another option is to use the RegisterInitializer method:
container.RegisterInitializer<BaseControllerType>(controller =>
{
controller.UnitOfWork = container.GetInstance<IUnitOfWork>();
}
It keeps all configuration in your composition root and does not pollute your code base with all kinds of attributes.
Update: (as promised)
While this is a direct answer to your question I have to provide you with a better option, because the usage of a base class for this is a IMO not the correct design, for multiple reasons.
Abstract classes can become real PITA classes as they tend to grow towards a god class which has all kinds of cross cutting concerns
An abstract class, especially when used with property injection, hides the needed dependencies.
With focus on point 2. When you want to unit test a controller which inherits from the base controller, you have no way of knowing that this controller is dependent on IUnitOfWork. This you could solve by using constructor injection instead of property injection:
protected abstract class BaseController : Controller
{
protected readonly IUnitOfWork uoW;
protected BaseController (IUnitOfWork uoW)
{
this.uoW = uoW;
}
}
public class SomeController : BaseController
{
public SomeController(IUnitOfWork uoW) : base(uoW) { }
}
While this solves point 2, point 1 is still lurking. The main reason you're wanting this, as you say, is because you do not want to commit your changes in every Action method. Changes must just be saved by the context when the request is done. And thinking about design in this way is a good thing, because Saving changes is, or can be seen as a cross cutting concern and the way you're implementing this is more or less known as AOP.
If it's comes to AOP, especially if you're working with atomic actions in the action methods of your controllers, there is a far better, more SOLID and more flexible design possible which deals with this very nicely.
I'm referring to the Command/Handler pattern which is described in great detail here (also read this for the query part of your application).
With this patterns you don't inject a generic IUnitOfWork abstraction, but inject the specific needed ICommandHandler<TCommand> abstractions.
The action methods would fire the responsible commandhandler for this specific action. All commandhandlers can simple be decorated by a single open-generic SaveChangesCommandHandlerDecorator, 'ValidationDecorator', 'CheckPermissionsDecorator', etc...
A quick example:
public class MoveCustomerCommand
{
public int CustomerId;
public Address NewAddress;
}
public class MoveCustomerCommandHandler : ICommandHandler<MoveCustomerCommand>
{
public void Handle(MoveCustomerCommand command)
{
// retrieve customer from database
// change address
}
}
public class SaveChangesCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> decoratee;
private readonly DbContext db;
public SaveChangesCommandHandlerDecorator(
ICommandHandler<TCommand> decoratee, DbContext db)
{
this.decoratee = decoratee;
this.db = db;
}
public void Handle(TCommand command)
{
this.decoratee.Handle(command);
this.db.SaveChanges();
}
}
// Register as
container.Register(typeof(ICommandHandler<>), new []{Assembly.GetExecutingAssembly() });
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(SaveChangesCommandHandlerDecorator<>));
// And use in controller as
public ActionResult MoveCustomer(int customerId, Address address)
{
var command = new MoveCustomerCommand
{ CustomerId = customerId, Address = address };
this.commandHandler.Handle(command);
return View(new ResultModel());
}
This keeps your controllers clean and let it do what it must do, namely be the layer between the business logic (the commandhandler implementation in this case) and the view.
Need to create the following:
First create the attribute class
[System.AttributeUsage(System.AttributeTargets.Property]
public class Inject : Attribute
{
}
Then create a custom property behavior
class PropertySelectionBehavior<TAttribute> : IPropertySelectionBehavior
where TAttribute : Attribute
{
public bool SelectProperty(Type type, PropertyInfo prop)
{
return prop.GetCustomAttributes(typeof(TAttribute)).Any();
}
}
Finally tell the container to use custom behavior
container.Options.PropertySelectionBehavior = new PropertySelectionBehavior<Inject>();
All that is left to do is decorate the property with the attribute
[Inject]
public IUnitOfWork UnitOfWork { get; set; }

Why can't I use Get<ClassNameOfConcreteInstance> as a method name in Ninject Extension Factory?

Look at this very simple example: Calling CreateCar it works, calling GetCar it fails, saying "Error activating ICar: No matching bindings are available, and the type is not self-bindable".
public interface ICar { }
public class Car : ICar
{
public Car(string carType) { }
}
public interface ICarFactory
{
ICar CreateCar(string carType); // this is fine
ICar GetCar(string carType); // this is bad
}
public class CarModule : NinjectModule
{
public override void Load()
{
Bind<ICarFactory>().ToFactory();
Bind<ICar>().To<Car>();
}
}
public class Program
{
public static void Main()
{
using (var kernel = new StandardKernel(new FuncModule(), new CarModule()))
{
var factory = kernel.Get<ICarFactory>();
var car1 = factory.CreateCar("a type");
var car2 = factory.GetCar("another type");
}
}
}
Is assume it must be related to some kind of convention with Get*ClassName* (something like the NamedLikeFactoryMethod stuff). Is there any way to avoid this convention to be applied? I don't need it and I don't want it (I already wasted too much time trying to figure out why the binding was failing, it was just luck that I made a typo in 1 of my 10 factories and I noticed it to work just because the factory method name was "Ger" instead of "Get").
Thanks!
Yes, there is a convention, where the Get is used to obtain instances using a named binding. The factory extension generates code for you so you don't have to create boilerplate code for factories. You don't need to use it, if you don't want to.
But if you do, you are bound to its conventions. Use Create to build instances and Get to retrieve instances via a named binding.
All this is documented in the wiki.

Prevent Ninject from calling Initialize multiple times when binding to several interfaces

We have a concrete singleton service which implements Ninject.IInitializable and 2 interfaces. Problem is that services Initialize-methdod is called 2 times, when only one is desired. We are using .NET 3.5 and Ninject 2.0.0.0.
Is there a pattern in Ninject prevent this from happening. Neither of the interfaces implement Ninject.IInitializable. the service class is:
public class ConcreteService : IService1, IService2, Ninject.IInitializable
{
public void Initialize()
{
// This is called twice!
}
}
And module looks like this:
public class ServiceModule : NinjectModule
{
public override void Load()
{
this.Singleton<Iservice1, Iservice2, ConcreteService>();
}
}
where Singleton is an extension method defined like this:
public static void Singleton<K, T>(this NinjectModule module) where T : K
{
module.Bind<K>().To<T>().InSingletonScope();
}
public static void Singleton<K, L, T>(this NinjectModule module)
where T : K, L
{
Singleton<K, T>(module);
module.Bind<L>().ToMethod(n => n.Kernel.Get<T>());
}
Of course we could add bool initialized-member to ConcreteService and initialize only when it is false, but it seems quite a bit of a hack. And it would require repeating the same logic in every service that implements two or more interfaces.
Thanks for all the answers! I learned something from all of them! (I am having a hard time to decide which one mark correct).
We ended up creating IActivable interface and extending ninject kernel (it also removed nicely code level dependencies to ninject, allthough attributes still remain).
Ninject 3
Ninject 3.0 now supports multiple generic types in the call to bind, what you are trying to do can be easily accomplished in a single chained statement.
kernel.Bind<IService1, IService2>()
.To<ConcreteService>()
.InSingletonScope();
Ninject 2
You are setting up two different bindings K=>T and L=>T. Requesting instances of L will return transient instances of T. Requesting K will return a singleton instance of T.
In Ninject 2.0, an objects scope is per service interface bound to a scope callback.
When you have
Bind<IFoo>...InSingletonScope();
Bind<IBar>...InSingletonScope();
you are creating two different scopes.
You are saying
"Binding to IFoo will resolve to the same object that was returned
when .Get was called."
and
"Binding to IBar will resolve to the same object that was returned
when .Get was called."
you can chain the bindings together, but you will need to remove IInitializable as it will cause duplicate initialization when the instance is activated:
kernel.Bind<IBoo>()
.To<Foo>()
.InSingletonScope();
.OnActivation(instance=>instance.Initialize());
kernel.Bind<IBaz>()
.ToMethod( ctx => (IBaz) ctx.Kernel.Get<IBoo>() );
or
kernel.Bind<Foo>().ToSelf().InSingletonScope()
.OnActivation(instance=>instance.Initialize());
kernel.Bind<IBaz>().ToMethod( ctx => ctx.Kernel.Get<Foo>() );
kernel.Bind<IBoo>().ToMethod( ctx => ctx.Kernel.Get<Foo>() );
in order to get multiple interfaces to resolve to the same singleton instance. When I see situations like this, I always have to ask, is your object doing too much if you have a singleton with two responsibilities?
Update : Pretty sure using V3's multiple Bind overloads will address this; See this Q/A
Good question.
From looking at the source, the initialize bit happens after each Activate. Your Bind...ToMethod counts as one too. The strategy is pretty uniformly applied - there's no way to opt out in particular cases.
Your workaround options are to use an explicit OnActivation in your Bind which will do it conditionally (but to do that in a general way would require maintaining a Set of initialized objects (havent looked to see if there is a mechanism to stash a flag against an activated object)), or to make your Initialize idempotent through whatever means is cleanest for you.
EDIT:
internal interface IService1
{
}
internal interface IService2
{
}
public class ConcreteService : IService1, IService2, Ninject.IInitializable
{
public int CallCount { get; private set; }
public void Initialize()
{
++CallCount;
}
}
public class ServiceModule : NinjectModule
{
public override void Load()
{
this.Singleton<IService1, IService2, ConcreteService>();
}
}
Given the following helpers:
static class Helpers
{
public static void Singleton<K, T>( this NinjectModule module ) where T : K
{
module.Bind<K>().To<T>().InSingletonScope();
}
public static void Singleton<K, L, T>( this NinjectModule module )
where T : K, L
{
Singleton<T, T>( module );
module.Bind<K>().ToMethod( n => n.Kernel.Get<T>() );
module.Bind<L>().ToMethod( n => n.Kernel.Get<T>() );
}
}
#Ian Davis et al. The problem is that:
class Problem
{
[Fact]
static void x()
{
var kernel = new StandardKernel( new ServiceModule() );
var v1 = kernel.Get<IService1>();
var v2 = kernel.Get<IService2>();
var service = kernel.Get<ConcreteService>();
Console.WriteLine( service.CallCount ); // 3
Assert.AreEqual( 1, service.CallCount ); // FAILS
}
}
Because each activation (per Bind) initialises each time.
EDIT 2: Same when you use the following slightly more stripped down version:
static class Helpers
{
public static void Singleton<K, L, T>( this NinjectModule module )
where T : K, L
{
module.Bind<T>().ToSelf().InSingletonScope();
module.Bind<K>().ToMethod( n => n.Kernel.Get<T>() );
module.Bind<L>().ToMethod( n => n.Kernel.Get<T>() );
}
}
I think one of the option is, you create the object your self in the module and bind your object the each of the interfaces.
BTW, try not to use any container specific code in your production code. If you have to do that, use some helper and isolate them in the module project.
public class ServiceModule : NinjectModule
{
public override void Load()
{
ConcreteService svc = new ConcreteService();
Bind<IService1>().ToConstant(svc);
Bind<IService2>().ToConstant(svc);
....
}
}