I have read a lot about this topic, but couldn't grasp it all the way.
I am trying to use the Ninject.Extensions.Factory instead of my factory to create new objects depending on user input. I want to fully use the Ninject functionality and the IoC concept.
Now the code looks like this:
interface IFeatureFactory
{
IFeature createFeature(int input);
}
and:
class BasicFeatureFactory : IFeatureFactory
{
public IFeature createFeature(int input)
{
switch (input)
{
case 1:
return new FirstFeature();
case 2:
return new SecondFeature();
default:
return null;
}
}
}
In the future, the IFeature will have dependencies so I want to do it the IoC way.
EDIT:
consumer class - the IFeatureFactory and IUILayer are injected into the FeatureService constructor and resolved using Ninject.
private IFeatureFactory featureFactory;
private IUILayer uiHandler;
public FeatureService(IFeatureFactory featureFactory, IUILayer uiHandler)
{
this.featureFactory = featureFactory;
this.uiHandler = uiHandler;
}
public void startService()
{
int userSelection = 0;
uiHandler.displayMenu();
userSelection = uiHandler.getSelection();
while (userSelection != 5)
{
IFeature feature = featureFactory.createFeature(userSelection);
if (feature != null)
{
IResult result = feature.execFeature();
uiHandler.displayResult(result);
}
else
{
uiHandler.displayErrorMessage();
}
uiHandler.displayMenu();
userSelection = uiHandler.getSelection();
}
}
and IFeature class:
public interface IFeature
{
IResult execFeature();
}
Bindings:
public override void Load()
{
Bind<IFeatureFactory>().To<BasicFeatureFactory>();
Bind<IUILayer>().To<ConsoleUILayer>();
}
How can I convert this Factory Pattern to IoC with the Ninject.Extensions.Factory? keep in mind the creation of the IFeature is dependent on the user input.
To me it is look like you have 2 options to refactor your code to get the full benefits of ninject.
The way you're working now is no different than pure di (which there is nothing wrong about it and it is better it some cases) but as you said you want to fully use ninject functionality.
Option one
Instead of injecting IFeatureFactory into FeatureService inject the interface IFeatureProvider which will look like this:
public interface IFeatureProvider
{
IFeature GetFeature(int featureType);
}
Now your FeatureService will get the requested features from this provider instead of the factory.
You will need to implement IFeatureProvider and for that you will need 2 more interfaces IFirstFeatureFactory and ISecondFeatureFactory:
public interface IFirstFeatureFactory
{
IFeature CreateFirstFeature();
}
public interface ISecondFeatureFactory
{
IFeature CreateSecondFeature();
}
And now IFeatureProvider impelementaion:
public class FeatureProvider: IFeatureProvider
{
private readonly IFirstFeatureFactory _firstFeatureFactory;
private readonly ISecondFeatureFactory _secondFeatureFactory;
public FeatureProvider(IFirstFeatureFactory firstFeatureFactory, ISecondFeatureFactory secondFeatureFactory)
{
_firstFeatureFactory=firstFeatureFactory;
_secondFeatureFactory=secondFeatureFactory;
}
public IFeautre GetFeature(int featureType)
{
switch(featureType)
{
case 1:
return _firstFeatureFactory.CreateFirstFeature();
case 2:
return _secondFeatureFactory.CreateSecondFeature();
default:
return null;
}
}
}
the thing you should notice that i just extract the object who is responsible for the 'new' into another interface.
We will not implement the two factory interfaces as ninject will do it for us if we will bind it properly.
The binding:
Bind<IFeature>().ToFeature<FirstFeature>().NamedLikeFactoryMethod((IFirstFeatureFactory o) => o.CreateFirstFeature());
Bind<IFeature>().ToFeature<SecondFeature>().NamedLikeFactoryMethod((ISecondFeatureFactory o) => o.CreateSecondFeature());
Bind<IFirstFeatureFactory>().ToFactory();
Bind<ISecondFeatureFactory>().ToFactory();
Bind<IFeatureProvider>().To<FeatureProivder>();
This 'NameLikeFactoryMethod' binding is equivalent the using of named binding as i did here and it is now the recommended way by ninject for factories.
The importent thing to notice here you do not implement IFirstFeatureFactory and ISecondFeatureFactory by yourself and you're using ninject functionallity for that.
The major disadvantage of this option is when we need to add more features we will need to create except for the feature itself another FeatureFactory and also change the FeatureProvider to handle it as well.
If the features are not changed very often this option can be good and simple but if they do it can become maintenance nightmare and that is why i suggest option 2.
Option two
In this option we will not create any provider class at all and will put all the creation logic inside the factory.
IFeatureFactory interface will look pretty similar to the one you have now, but instead of using an int as parameter we will use a string (is will suit better with the named binding as we will see soon).
public interface IFeatureFactory
{
IFeature CreateFeature(string featureName);
}
We will not implement this interfaces by ourselves and let ninject do it for us, however we will need to tell ninject to use the first parameter of CearteFeature to detect which implementation to instantiate(FirstFeatue or SecondFeature).
For that we will need custom instance provider with this behavior as the StandardInstanceProvider using other convention to choose which implementation to instantiate(the default convention in this article).
Fortunately ninject show as exactly how we can implement it very quickly by UseFirstArgumentAsNameInstanceProvider.
Now the binding:
Bind<IFeature>().To<FirstFeature>().Named("FirstFeature");
Bind<IFeature>().To<FirstFeature>().Named("SecondFeature");
Bind<IFeatureFactory>().ToFactory(() => new UseFirstArgumentAsNameInstanceProvider());
The things to notice here:
We will not implement the factory interface by ourselves.
We are using named binding for each implementation and we will get the implementation from the factory according to the featureName we will pass to the factory method (this is why i prefer the parameter to be string).
Notice that if you pass feature name that is not "FirstFeature" or "SecondFeature" exception will be thrown.
We are using UseFirstArgumentAsNameInstanceProvider as our instance provider for our factory as mentioned before.
This has solved the problem in the first option as if we want to add new feature we well just need to create it and bind it to his interface with his name.
Now the client of the factory can ask from the factory feature with this new name without the need of changes in other classes.
Conslucsion
By choosing one of this options above over pure di we will get the benefits of letting ninject kernel create our object in the factories instead of doing all the 'new' on our own.
Although there is nothing wrong about not using IoC container this can really helps us in cases there is a big dependencies graph inside IFeature implementations as ninject will inject them for us.
By doing one of this options we are fully using ninject functionality without using a 'Service locator' which is considered as an anti pattern.
You can inject the features into the BasicFeatureFactory's constructor.
class BasicFeatureFactory : IFeatureFactory
{
FirstFeature feature1;
SecondFeature feature2;
public BasicFeatureFactory(FirstFeature feature1, SecondFeature feature2) {
this.feature1 = feature1;
this.feature2 = feature2;
}
public IFeature createFeature(int input) {
switch (input) {
case 1: return this.feature1;
case 2: return this.feature2;
default: return null;
}
}
}
Related
Hi i am trying to apply the SOLID Principle to my code until i came across the interface and Dependency Inversion.
i am just having trouble with the constructor of FlightValidator class.
please can do advice?enter code here
you can get the full project here: https://www.sendspace.com/file/zk022f
i am confused on this class. in how do i create an instance of it?
public class FlightValidator
{
private IValidator _validator;
private GeneralFlightValidation _generalFlightValidation;
private BasicFlightValidation _basicFlightValidation;
private int flightRuleType;
public FlightValidator(IValidator _validator,
int flightRuleType
)
{
this._validator = _validator;
this.flightRuleType = flightRuleType;
}
public void GetFlightRule(ScheduledFlight scheduledFlight)
{
switch(this.flightRuleType)
{
case (short)FlightRuleType.STANDARD:
{
this._validator.FlightValidator(scheduledFlight);
break;
}
case (short)FlightRuleType.BASIC:
{
this._validator.FlightValidator(scheduledFlight);
break;
}
default:
{
this._validator.FlightValidator(scheduledFlight);
break;
}
}
}
}
public enum FlightRuleType : int
{
STANDARD,
BASIC
}
i am confused on this class. in how do i create an instance of it?
You can just pass the dependency to the constructor:
IValidator validator = ...
FlightValidator flightValidator = new FlightValidator(validator);
or, if you're using an IoC container (e.g. Unity):
FlightValidator flightValidator = container.Resolve<FlightValidator>();
Anyway, I find your code a bit confusing. Your FlightValidator class depends on an IValidator, which itself has a FlightValidator method (very bad name for a method by the way)... So what is the FlightValidator class good for, if it just calls another thing that does the flight validation?
What you're looking at here is Dependency Injection. The general idea is to remove the dependency from the class and injecting said dependency via the constructor. This allows your class to have less responsibilities, promotes re-use, which results in a more agile solution.
To instantiate this class, you can use poor man's dependency injection, like this:
IValidator myValidator = new SomeValidator();
FlightValidator flightValidator = new FlightValidator(myValidator, 69);
For a more elegant approach, you can use Inversion of Control.
I am currently stuck at trying to write a factory class that doesn't rely on service location.
The only other alternative I can think of is to use constructor injection to inject all possible instances, but that may lead to surprises as classes are passed via reference.
It is also possibly going to be costly and messy once the number of possible providers grow.
The providers themselves are full complex classes that have their own dependencies so manual construction is out of the picture.
Updated service location example:
public class ProviderFactory : IProviderFactory
{
private readonly IProviderConfigurationService _providerConfigurationService;
public enum SearchType
{
Foo,
Bar
}
public ProviderFactory(IProviderConfigurationService providerConfigurationService)
{
_providerConfigurationService = providerConfigurationService;
}
public Collection<IProvider> GetProviderInstances(SearchType searchType)
{
// Provider configuration service will read a XML/DB store to retrieve list of search providers applicable for a search type
var providerList = _providerConfigurationService.GetProviderList(searchType);
return new Collection<IProvider>(providerList.ForEach(x=> ServiceLocator.GetInstance(typeof(x))).ToList()) ;
}
}
What are my other options? I am currently using Unity for DI.
An alternative is to pass a Func<Type, object> to the constructor and to implement the function through your container:
unity.RegisterInstance<Func<Type, object>>(t => unity.Resolve(t))
Then in your class:
public ProviderFactory(Func<Type, object> createFunc, IProviderConfigurationService pcs)
{
_createFunc = createFunc;
}
public Collection<IProvider> GetProviderInstances(SearchType searchType)
{
var providerList = _providerConfigurationService.GetProviderList(searchType);
return new Collection<IProvider>(providerList.Select(_createFunc).ToList());
}
You are missing an abstraction.
Your ProviderFactory should implement an IProviderFactory abstraction. This way you can place that interface in a base library of your application and you can place the ProviderFactory implementation inside your Composition Root. For code that lives inside your composition root, it is okay to reference the DI library, and in that case you're not using service location.
I have recently solved a very similar issue in my own code by using a DI framework. To satisfy Dependency Inversion, the factory constructor should accept an interface (as the other answers have said), but to get the framework to inject the right type is tricky without having a massive list of arguments detailing each possible concretion.
SimpleInjector allows you to register all concretions of a given abstraction with:
Container.RegisterCollection(typeof(IProvider), new [] {typeof(TKnown).Assembly,...});
Your XML could list the (possibly external) assemblies where the concretions are defined and you could build the assembly array from there. Then your factory just needs to accept them all and pick one, perhaps based on the searchType you mentioned.
public class ProviderFactory
{
private List<IProvider> providers;
public ProviderFactory(IEnumerable<IProvider> providers)
{
this.providers = providers.ToList();
}
public IProvider GetProvider(string searchType)
{
// using a switch here would open the factory to modification
// which would break OCP
var provider = providers.SingleOrDefault(concretion => concretion.GetType().Name == searchType);
if (provider == null) throw new Exception("No provider found of that type. Are you missing an assembly in the RegisterCollection for IProvider?");
return provider;
}
I know I'm way late to the party on this but assuming other folks don't see this approach as problematic, it might be useful.
I have been looking for Strategy Pattern and I saw This link which the guy has explained this pattern very well.
But as far as I know (maybe right or wrong) you shouldn't make a new class in another class (for the sake of being loosely coupled).
this.motor = new Motor(this)
Is there a better kind of implementation for that to not violate the principles (like IoC)?
It would produce a more maintainable code to define both your strategy and context as interfaces:
interface IStrategy<T> where T : IContext
{
T Context { get; }
void Execute();
}
// this cab have other structures too depending on your common logic
// like being generic
interface IContext
{
}
I, myself prefer constructor injection. But in this case property injection is needed because one may need to change the strategy at run time.
Now you can implement/inject your concrete types.
You can use Constructor Injection.
public class MyClass{
public MyClass(Motor motor){
this.motor = motor;
}
}
Then, it's up to your IOC container to supply the needed dependency.
Sure, there are many possibilities. What about a strategy factory?
this.motor = MotorFactory.newMotor(MotorFactory.BOOST);
or simply a mutator method for injection (assuming IMotor is the abstract interface for motors:)
void setMotor(IMotor m) {
this.motor = m;
}
u can use "dynamic" in c# instead like this:
Method(dynamic input)
Method(DTO1 input) Method(DTO2 input) Method(DTO3 input)
I'm trying to remove a Service Locator from an abstract base class, but I'm not sure what to replace it with. Here is a psuedo-example of what I've got:
public abstract class MyController : Controller
{
protected IKernel kernel;
public MyController(IKernel kernel) { this.kernel = kernel); }
protected void DoActions(Type[] types)
{
MySpecialResolver resolver = new MySpecialResolver(kernel);
foreach(var type in types)
{
IMyServiceInterface instance = resolver.Get(type);
instance.DoAction();
}
}
}
The problem with this is that the instanciator of a derived class doesn't know what bindings the kernel must have in order to keep MySpecialResolver from throwing an exception.
This might be intrinsicly intractable because I don't know from here which types I'll have to resolve. The derived classes are responsible for creating the types parameter, but they aren't hardcoded anywhere. (The types are based on the presence of attributes deep within the derived class's composition hierarchy.)
I've trying to fix this with lazy loading delegates, but so far I haven't come up with a clean solution.
Update
There are really two issues here, one is that the IoC container is passed to the controller, acting as a service locator. This is easy to remove--you can move the location up or down the call stack using all sorts of techniques.
The second issue is the difficult one, how can you ensure that the controller has the necessary services when the requirements aren't exposed until runtime. It should have been obvious from the start: you can't! You will always be dependent upon either the state of the service locator or contents of a collection. In this particular case no amount of fiddling will ever resolve the problem described in this article with staticly typed dependencies. I think that what I'm going to end up doing is passing a Lazy array into the controller constructor and throwing an exception if a required dependency is missing.
I agree with #chrisichris and #Mark Seemann.
Ditch the kernel from the controller. I'd switch your resolver composition a little bit so that your controller can remove the dependency on the IoC container and allow the resolver to be the only item that worries about the IoC container.
Then I would let the resolver get passed into the constructor of the controller. This will allow your controller to be far more testable.
For example:
public interface IMyServiceResolver
{
List<IMyServiceInterface> Resolve(Type[] types);
}
public class NinjectMyServiceResolver : IMyServiceResolver
{
private IKernal container = null;
public NinjectMyServiceResolver(IKernal container)
{
this.container = container;
}
public List<IMyServiceInterface> Resolve(Type[] types)
{
List<IMyServiceInterface> services = new List<IMyServiceInterface>();
foreach(var type in types)
{
IMyServiceInterface instance = container.Get(type);
services.Add(instance);
}
return services;
}
}
public abstract class MyController : Controller
{
private IMyServiceResolver resolver = null;
public MyController(IMyServiceResolver resolver)
{
this.resolver = resolver;
}
protected void DoActions(Type[] types)
{
var services = resolver.Resolve(types);
foreach(var service in services)
{
service.DoAction();
}
}
}
Now your controller isn't coupled to a specific IoC container. Also your controller is much more testable since you can mock the resolvers and not require an IoC container at all for your tests.
Alternatively, if you don't get to control when a controller is instantiated, you can modify it slightly:
public abstract class MyController : Controller
{
private static IMyServiceResolver resolver = null;
public static InitializeResolver(IMyServiceResolver resolver)
{
MyController.resolver = resolver;
}
public MyController()
{
// Now we support a default constructor
// since maybe someone else is instantiating this type
// that we don't control.
}
protected void DoActions(Type[] types)
{
var services = resolver.Resolve(types);
foreach(var service in services)
{
service.DoAction();
}
}
}
You would then call this at your application start up to initialize the resolver:
MyController.InitializeResolver(new NinjectMyServiceResolver(kernal));
We did this to handle elements created in XAML who require dependencies resolved but we wanted to remove Service Locator like requests.
Please excuse any syntactical errors :)
I'm writing a blog post series on the topic of refactoring an MVVM application with Service Locator calls in the view models you might find interesting. Part 2 is coming soon :)
http://kellabyte.com/2011/07/24/refactoring-to-improve-maintainability-and-blendability-using-ioc-part-1-view-models/
Maybe you should just do away the Kernel, Types and MySpecialResolver and let the subclasses call DoActions with the IMyServiceInterface instances they need as argument directly. And let the subclasses decide how they get to these instances - they should know best (or in case they don't know which exactly the one who ever decides which instances of IMyServiceInterface are needed)
I would have liked to have a bit more information before posting this answer, but Kelly put me on the spot. :) Telling me to put my code where my mouth is, so to speak.
Like I said in my comment to Kelly, I disagree with moving the resolver/locator from a static implementation to an injected implementation. I agree with ChrisChris that the dependencies the derived type needs should be resolved in that class and not delegated to the base class.
That said, here is how I would remove the service location...
Create Command Interface
First of all I would create a command interface for the specific implementation. In this case the types sent with the DoActions method are generated from attributes, so I would create an IAttributeCommand. I am adding a Matches method to the command in order to declare the command for use by certain types.
public interface IAttributeCommand
{
bool Matches(Type type);
void Execute();
}
Add Command Implementations
To implement the interface, I pass in the specific dependencies I need to execute my command (to be resolved by my container). I add a predicate to my Matches method, and define my Execute behavior.
public class MyTypeAttributeCommand : IAttributeCommand
{
MyDependency dependency;
SomeOtherDependency otherDependency;
public MyTypeAttributeCommand (MyDependency dependency, ISomeOtherDependency otherDependency)
{
this.dependency = dependency;
this.otherDependency = otherDependency
}
public bool Matches(Type type)
{
return type==typeof(MyType)
}
public void Execute()
{
// do action using dependency/dependencies
}
}
Register Commands with Container
In StructureMap (use your favorite container), I would register the array like so:
Scan(s=>
{
s.AssembliesFromApplicationBaseDirectory();
s.AddAllTypesOf<IAttributeCommand>();
s.WithDefaultConventions();
}
Select and Execute Commands Based on Type
Finally, on the base class, I define an IAttributeCommand array in my constructor arguments to be injected by the IOC container. When the derived type passes in the types array, I will execute the correct command based on the predicate.
public abstract class MyController : Controller
{
protected IAttributeCommand[] commands;
public MyController(IAttributeCommand[] commands) { this.commands = commands); }
protected void DoActions(Type[] types)
{
foreach(var type in types)
{
var command = commands.FirstOrDefault(x=>x.Matches(type));
if (command==null) continue;
command.Execute();
}
}
}
If you multiple commands can handle one type, you can change the implementation: commands.Where(x=>x.Matches(type)).ToList().ForEach(Execute);
The effect is the same, but there is a subtle difference in how the class is constructed. The class has no coupling to an IOC container and there is no service location. The implementation is more testable as the class can be constructed with its real dependencies, with no need to wire up a container/resolver.
Say I have a singleton-ish, factory-ish, reflection-ish class that receives some input, and spits back a new instance of a concrete implementation of some interface. What kind of design is this? Is there a better way to do what I want?
Here's some code to illustrate the point:
using System;
using System.Collections.Generic;
// static factory class
public static class ArticleFactory
{
// given an SKU, store the Type object for an IArticle object
private static Dictionary<string, Type> articleRegistry = new Dictionary<string, Type>();
// allow public registration of SKU-to-Type object relationships
public static bool Register(string sku, Type typeInfo)
{
if(!articleRegistry.ContainsKey(sku))
{
articleRegistry.Add(sku, typeInfo);
return true;
}
return false;
}
// given a SKU, give me an instance of the related IArticle object
public static IArticle NewArticle(string sku)
{
if(articleRegistry.ContainsKey(sku))
{
// use reflection to invoke the default constructor
return articleRegistry[sku].GetConstructor(Types.EmptyTypes).Invoke(null) as IArticle;
}
return null;
}
}
// example concrete-implementation of an IArticle
public class Jeans : IArticle
{
public decimal GetPrice() { return SomeDecimal(); }
}
// WHERE DO I CALL THIS LINE?
ArticleFactory.Register("0929-291", typeof(Jeans));
// Later on, if another group needs to write the class for Snowboards,
// how can they self-register their class, without changing any "Main()"
// or "Page_Init()" function?
Looks like you've already identified the pattern. It's the Factory Method Pattern. Or rather, a somewhat half-baked implementation of one. A slightly better approach would be to first make it an interface:
public interface IArticleFactory
{
IArticle CreateArticle(string sku);
}
Then implement the factory without any Reflection at all:
public class MyArticleFactory
{
private Dictionary<string, Func<IArticle>> instantiators =
new Dictionary<string, Func<Iarticle>>();
public MyArticleFactory()
{
Register("Jeans", () => new Jeans());
Register("Shirt", () => new Shirt());
// etc.
}
public IArticle CreateArticle(string sku)
{
Func<IArticle> instantiator;
if (creators.TryGetValue(sku, out instantiator))
return instantiator();
throw new UnknownSkuException(sku);
}
protected void Register(string sku, Func<IArticle> instantiator)
{
creators.Add(sku, instantiator);
}
}
A few important differences:
Registration isn't public, nor should it be. Registration usually either resides in a configuration file somewhere or is private.
Does not require the IArticle concrete types to have a default parameterless constructor. This can easily register articles with parameterized constructors (as long as it knows what parameters to use).
Throws an exception on duplicate registrations. I don't like the idea of simply returning false; if you try to register the same factory method twice, that ought to be considered a bug.
It's not static. You can replace this factory with a different factory. You can unit-test it.
Of course, an even better approach would just be to use any of the myriad of existing .NET Dependency Injection/Inversion of Control Frameworks, such as Ninject or AutoFac.
I don't know if it has a "name" as such, but it looks like some kind of manual service resolver. The problem I can see (from experience, sadly) is that it is inflexible in real terms, in that:
the registration only has a single configuration
it is hard to unit test
Personally I'd look at an IoC container if I was doing this in a new system; the IoC can handle this relationship, and provide a lot more capabilities for free (lifetimes, enrichment, extra setup, etc), and solve many associated problems.
BTW, it may be easier to:
return Activator.CreateInstance(articleRegistry[sku]);
I think what you're doing here is basically Dependency Injection (or Inversion of Control is what the cool kids call it). Have a look at these links:
Explanation from Wikipedia: http://en.wikipedia.org/wiki/Dependency_Injection
Two DI .Net frameworks:
StructureMap: http://structuremap.sourceforge.net/QuickStart.htm
Castle Windsor: http://www.castleproject.org/container/index.html
It's just a factory pattern that happens to use reflection in its implementation. Rather than using reflection, though, it would probably be more efficient to simply put instances of factory classes directly in the dictionary, though this might require some boilerplate code.