If I understand the Factory Pattern correctly, I might have a factory for creating my Repos that implements an interface like this ...
public interface IRepoFactory
{
T Get<T>() where T : IRepo
}
And in that factory a call to RepoFactory.Get<IRepo1>() will return a newly minted instance of a class implementing IRepo1.
So, in the definition of RepoFactory I will create a new instance of the appropriate type...
switch(...)
{
case typeof(IRepo1):
return new Repo1();
}
Or, I assume, I can define a constructor for Repofactory that takes, as parameters, an interface representing all of the possible return types...
public RepoFactory(IRepo1 repo1, IRepo2 repo2, ..., IRepoN repoN) : IRepoFactory
and let my IoC container do the work of creating the classes.
So, to my question. If I do create a constructor as above, doesn't that mean that each time I include IRepoFactory as a constructor parameter I will get a new instance of Repo1, Repo2,..., RepoN? Is that a resource heavy process? Is it a wasteful way to do things if, in any given case, I will likely need only a subset of the total number of available repos?
Is there a way of getting the IoC (Unity, in my case) to only create an instance at the time it is needed, a Lazy Loading, if you will? Or am I simply worrying about nothing?
You misunderstood Factory. Factory should create instances. That's mean nothing should be in factory constructor beside of Di container or LifeTimeScope.
You can use your own factory or you can use auto generated factory.
I'm not familiar Unity but I checked they have.
public class MyService : IMyService
{
private readonly Func<IRepo1> _repo1;
public MyService(Func<IRepo1> repo1)
{
_repo1 = repo1;
}
public void Method1()
{
var myRepo = _repo1();
}
public void Method2()
{
//Repo1 instance will be different than in Method1
var myRepo = _repo1();
}
}
If you have a container then you can let the container resolve the type of repo when needed.
Here is a rough example of how you can do it. Note you will change the code to suit you specific container and also the assumption here is that you would have also already configured the container to know hot to resolve the types you want.
public class DefaultRepoFactory : IRepoFactory {
IUnityContainer container;
public DefaultRepoFactory(IUnityContainer container) {
this.container = container;
}
public T Get<T>() where T : IRepo {
return (T)container.Resolve<T>();
}
}
Configuration
IUnityContainer myContainer = new UnityContainer();
IRepoFactory myDefaultFactory = new DefaultRepoFactory(myContainer);
myContainer.RegisterInstance<IRepoFactory>(myDefaultFactory);
Related
Here is a class which will be instantiated only once through out the lifetime of the application
public class SampleClass //instantiated only once
{
public void DoOpertation()//will be called by every incoming request
{
var dependentService = new SampleService();
//do operation on dependentService instance
....
}
}
Method "DoOpertation" operation will be called many time during the application lifetime.
In "DoOpertation" method I'm instantiating 'SampleService' using 'new' keyword which I don't want to do for the below reasons
It breaks single responsibility principle (SRP) as creating SampleService class instance is not SampleClass's responsibility
Create tight coupling between SampleClass & SampleService classes which makes unit testing harder atleast
I can't use DI container for constructor injection of dependencies as SampleClass get instantiated only once in the application lifetime but where as every invocation of DoOpertation method (which lives inside SampleClass) requires new instance of SampleService class to work properly.
How to inject SampleService class new instance on every invocation of DoOpertation() without using 'new' keyword?
Modification as per Athanasios Kataras's suggestion
Introduced new factory class
public class LoggerFactory : ILoggerFactory
{
public IEventLog CreateLogger(string type)
{
if (type == "Event")
return new EventLog();
else
return null;
}
}
public interface ILoggerFactory
{
IEventLog CreateLogger(string type);
}
On the class which instantiate only once,
public class SampleClass //instantiated only once
{
public void DoOpertation()//will be called by every incoming request
{
var eventLogBuilder = _factory.CreateLogger("Event");
//var dependentService = new SampleService(); //replace with above simple factory class call
//do operation on dependentService instance
....
}
}
I would go with a simple factory solution.
Create the IServiceFactory interface with the CreateService(options) function
Create a class implementing it with the responsibility of returning the proper service insurance.
Inject the factory implementation
In your function call the factory interface. This will also enable you to change the creation strategy in the future if you need it.
The solution going with the built in provider, looks like a service locator anti pattern to me, so I would advise against it.
Register Sampleclass as a singleton and SampleService as a transient.
Then inject IServiceProvider into SampleClass. Use the ServiceProvider to then create the SampleServer.
services.AddSingleton<SampleClass>();
services.AddTransient<SampleService>();
...
public class SampleClass //instantiated only once
{
private readonly IServiceProvider _provider;
public SampleClass(IServiceProvider provider)
{
_provider = provider;
}
public void DoOpertation()//will be called by every incoming request
{
var dependentService = _provider.GetService<SampleService>();
//do operation on dependentService instance
....
}
}
I'd like my app to be not strictly tied to an IOC, so basically my application should need to call an IOC factory pattern that solve the specific implementation on runtime.
So, first off I've created my interface:
IIOCService
interface IIOCService
{
void RegisterSingleton<RegisterType>()
where RegisterType : class;
void RegisterMultiple<RegisterType>()
where RegisterType : class;
void RegisterMultiple<RegisterType>(IEnumerable<Type> implementationTypes);
// and so on
}
then an implementation of IIOCService, using TinyIOC
class TinyIOCServiceImpl : IIOCService
{
private static readonly TinyIOCServiceImpl _Current = new TinyIOCServiceImpl();
public static TinyIOCServiceImpl Current
{
get
{
return _Current;
}
}
TinyIoC.TinyIoCContainer container;
public TinyIOCServiceImpl()
{
container = TinyIoC.TinyIoCContainer.Current;
}
public void RegisterSingleton<RegisterType>()
where RegisterType : class
{
container.Register(typeof(RegisterType)).AsSingleton();
}
// ...and so on
}
For the class that decides to resolve the implementation of the IOC container, I've created an IOCFactory
IOCFactory
class IOCFactory
{
public enum IOC { TinyIOC }
public IIOCService GetService(IOC iocType)
{
switch (iocType)
{
case IOC.TinyIOC:
return TinyIOCServiceImpl.Current;
default:
throw new NotSupportedException();
}
}
}
Now my question is:
Should I need to reinstantiate the factory for every class where IOC is needed or there is some more elegant way?
IIOCService iocService = new IOCFactory().GetService(IOCFactory.IOC.TinyIOC);
// code needed everytime I need to use IOC (i.e. ServiceLocator, ViewModelLocator, etc.)
// is this code a bit redundant ???
I agree that creating a wrapper around your IOC container is a bit redundant. But, if you need to call your IOC container to resolve a specific, on run-time determined, instance of an interface, you can create a resloving interface (not with the factory pattern, but staying within the IOC pattern). Something like this (this is too basic, just so you can get the idea):
public interface IResolve {
public T Resolve<T>();
}
You can create an implementation for this specific interface and expose it to your IOC container. There is no issue doing this in a single instance pattern.
When you need to resolve something in a class that was resolved by the IOC container, just add the IResolve to your constructor and you can address the IOC container without a dependency on whatever brand of IOC container is used.
I hope this brought some clarity for you?
I have an abstract factory like this.
public abstract class AbstractFactory
{
public abstract ISyncService GetSyncService(EntityType entityType);
}
And I have its concrete implementation like this.
public class SyncFactory : AbstractFactory
{
private readonly IOperatorRepository _operatorRepository;
public SyncFactory( IOperatorRepository operatorRepository)
{
_operatorRepository = operatorRepository;
}
public override ISyncService GetSyncService(EntityType entityType)
{
return new OperatorSyncService(_operatorRepository);
}
}
This concrete factory is accessed in a method like this.
public void MethodTobeTested()
{
var syncService =
new SyncFactory(_operatorRepository).GetSyncService(entityType);
}
Now I need to write a unit test for MethodTobeTested().
I mocked the return value of the GetSyncService() like this. But it's calling the actual OperatorSyncService, not the mock. I need this mock to mock another method inside OperatorSyncService
private Mock<SyncFactory> _syncServiceMock;
_syncServiceMock = new Mock<SyncFactory>();
_syncServiceMock.Setup(m => m.GetSyncService(operator)).Returns(_operatorSyncServiceMock.Object);
Any idea on how to resolve this?
In your SyncFactory implementation you inject an instance of IOperatorRepository. This is great because it allows you to inject a different version if needs be and creates a seem for you to use a mock implementation of IOperatorRepository.
You have also made an abstract factory which looks good but it looks like the problem is with your usage of the factory;
var syncService =
new SyncFactory(_operatorRepository).GetSyncService(entityType);
In your MethodToBeTested you create a concrete implementation of SyncFactory, this make the point of the abstract factory a little redundent since you cannot inject a different implementation. I don't know where you are geting your _operatorRepository instance from but I can see two ways forward.
In the constructor of the class that contains MethodToBeTested add a parameter that takes an instance of your abstract factory, then get your MethodToBeTested to use this injected factory instead of creating a new one, this would allow you to mock the whole factory - this is my recommended approach because the class containing MethodToBeTested would no longer need to know how to create a factory instance which it shouldn't if you are following the single responsibility principle. There would be no dependence on any concrete implementation.
As above but instead inject IOperatorRepository rather than the factory, you can then inject a mock IOperatorRepository but I would advise against this since you've done such a good job of creating all your abstractions to then cast this work aside and "new up" an instance of syncFactory and creating a concrete dependency
MethodToBeTested is tightly coupled to SyncFactory because the method is manually creating a new instance of SyncFactory. This makes mocking the dependency very difficult.
Assuming
public class ClassToBeTested {
public void MethodTobeTested() {
var syncService = new SyncFactory(_operatorRepository).GetSyncService(entityType);
//...other code
}
}
ClassToBeTested should be refactored to
public class ClassToBeTested {
private readonly AbstractFactory syncFactory;
public ClassToBeTested (AbstractFactory factory) {
this.syncFactory = factory
}
public void MethodTobeTested() {
var syncService = syncFactory.GetSyncService(entityType);
//...other code
}
}
This will allow the dependency to be mocked and injected into the class to be tested and accessed by the method to be tested. The class to be tested now only needs to know what it needs to know. It now no longer needs to be aware of IOperatorRepository.
The new in the method MethodTobeTested creates new instance so no mock can be injected. Inject the factory e.g. as parameter so it can be mocked in the test.
public void MethodTobeTested(AbstractFactory factory)
{
EntityType entityType = null;
var syncService = factory.GetSyncService(entityType);
}
[TestMethod]
public void Method_Condition_Result()
{
// Arrange
TestedClass tested = new TestedClass();
Mock<ISyncService> syncServiceMock = new Mock<ISyncService>();
Mock<AbstractFactory> factoryMock = new Mock<AbstractFactory>();
factoryMock.Setup(f => f.GetSyncService(It.IsAny<EntityType>())).Returns(syncServiceMock.Object);
// Act
tested.MethodTobeTested(factoryMock.Object);
// Assert
// ...
}
I have a console application where I need to execute a certain feature based on input from the user. If the user puts in "feature 1" -> I execute Feature 1, and so on.
I am trying to write this project as clean and as generic as possible, and I want to use the IoC and SOLID concepts, and i am kinda stuck.
What I have so far:
public interface IFeature
{
String execFeature();
}
and
interface IFeatureFactory
{
IFeature createFeature(String input);
}
My first thought was just to have a switch case on the concrete Factory class about the input from the user, and create the concrete Feature accordingly, but I bet there is a better way to do it with IoC.
I read about Ninject factory extension, but didn't understand how to use it in my project.
Whatis the best way to do the factory pattern with IoC/Ninject?
If your IFeature implementations does not have other dependencies than using your approach is fine and very simple. For example lets say you have 2 implementations of IFeature - SomeFeature and OtherFeature that both have parametersless constructor. Your factory implementation as you suggest would be something like that:
public class FeatureFactory: IFeatureFactory
{
IFeature CreateFeature(string input)
{
if(input=="SomeFeature")
{
return new SomeFeature();
}
else
{
return new OtherFeature ();
}
}
}
However when your IFeature implementations have their own dependencies using this approach you lose the point of using Ninject and IoC.
For example lets say That SomeFeature looks something like that:
public class SomeFeature : IFeature
{
private readonly IDependency1 _dependency1;
private readonly IDependency2 _dependency2;
public SomeFeature (IDependency1 dependency1, IDependency2 dependency2)
{
_dependency1=dependency1;
_dependency2=dependency2;
}
string execFeature()
{
//Some code here...
}
}
And OtherFeature is similar...
public class OtherFeature: IFeature
{
private readonly IDependency1 _dependency1;
private readonly IDependency2 _dependency2;
public OtherFeature(IDependency1 dependency1, IDependency2 dependency2)
{
_dependency1=dependency1;
_dependency2=dependency2;
}
string execFeature()
{
//Some code here...
}
}
Now your factory would become something like that:
public class FeatureFactory: IFeatureFactory
{
IFeature CreateFeature(string input)
{
if(input=="SomeFeature")
{
return new SomeFeature(new Dependency1Implementation(), new Dependency2Implementation());
}
else
{
return new OtherFeature(new Dependency1Implementation(), new Dependency2Implementation());
}
}
}
This is the place when you can use the power of the ninject.extensions.factory
by using the container to solve this dependencies for you.(This dependencies can have their own dependencies and it can get messy very quickly).
As other mentioned you can bind every IFeature implementation using named binding.
Bind<IFeature>().To<SomeFeature>().Named("SomeFeature");
Bind<IFeature>().To<OtherFeature>().Named("OtherFeature");
Of Course you should bind other dependencies as well
Bind<IDependency1>().To<Dependency1Implementation>();
Bind<IDependency2>().To<Dependency2Implementation>();
And then bind the IFeatureFactory to Factory using the factory extension.
Bind<IFeatureFactory>().ToFactory();
What you have to do is create factory method for each of your IFeature implementations in IFeatureFactory and call it Get... according to the Feature named binding.
public interface IFeatureFactory
{
IFeature GetSomeFeature();
IFeature GetOtherFeature();
}
Now ninject will implement(!) this class for you and know which implementation to choose for each method.(There is no need for service locator....)
You can use switch statement over the input in your client to choose which factory method to call or you can wrap it in some provider class that will have the switch statement in it, in both cases you will not have to do the 'new' for IFeature implementations yourself.
Of Course you can pass parameters to the implementations constructors by the factory methods if you need to and other more complex things.
I suggest you to read this for further information.
Edit
I would like to emphasis you don't have to write factory method for each implementation, you can use the same method for all (It is possible but more complex). To do it you will need to create custom instance provider to detect which implementation to instantiate (according to the factory parameters for example), more about this in the link above and here.
You can use Named Bindings. Example code:
Bind<IFeature>().To<Feature1>().Named("Feature1");
Bind<IFeature>().To<Feature2>().Named("Feature2");
For more info
Edit
If you don't like Service locator pattern, above approach is not good for your case because you have to use IKernel to resolve IFeature.
One of the main idea of IoC that you should not have dependencies between components of your solution. So it's good approach to use only interfaces and don't create new instances of your classes with keyword "new".
Your issue can't be solved in a simple and elegant way because you can inject only interface which all you features implement.
So you have some features and them implementations:
internal interface IFeature
{
}
internal interface IFeature1 : IFeature
{
}
internal interface IFeature2 : IFeature
{
}
And a factory:
internal interface IFeatureFactory
{
IFeature GetInstance(string featureName);
}
internal class FeatureFactory : IFeatureFactory
{
private readonly ITypeFactory<IFeature1> feature1;
private readonly ITypeFactory<IFeature1> feature2;
private readonly Dictionary<string, ITypeFactory<IFeature>> featuresContainer;
public FeatureFactory(ITypeFactory<IFeature1> feature1, ITypeFactory<IFeature1> feature2)
{
this.feature1 = feature1;
this.feature2 = feature2;
featuresContainer = new Dictionary<string, ITypeFactory<IFeature>>
{
{"Feature1", feature1},
{"Feature2", feature1}
};
}
public IFeature GetInstance(string featureName)
{
if (!featuresContainer.ContainsKey(featureName))
throw new Exception(string.Format("Can't create feature {0}", featureName));
return featuresContainer[featureName].Create();
}
}
You can inject all this stuff in this way:
Bind<IFeatureFactory>().To<FeatureFactory>().InSingletonScope();
Bind<IFeature1>().To<Feature1>();
Bind<IFeature2>().To<Feature2>();
Bind<ITypeFactory<IFeature1>>().ToFactory();
Bind<ITypeFactory<IFeature2>>().ToFactory();
The main idea is that you have only one instance of feature factory for application and you store injected factories of your features. So when you access to IFeatureFactory first time Ninject will create a singleton instance of it. But your features instances will create only when you'll call GetInstance() method.
To make this code work you should add new interface:
public interface ITypeFactory<out T>
{
T Create();
}
And install NuGet package:
https://www.nuget.org/packages/Ninject.Extensions.Factory/
I have to apply the following methods for Ninject, IoC and factory pattern.
Step 1:
Added binding to IOC container
Bind<IFeature>().To<SomeFeature>().Named(nameof(SomeFeature));
Bind<IFeature>().To<SomeFeature>().Named(nameof(SomeFeature));
Step 2:
Create an extension method to resolve your dependency
public class Resolver
{
[Inject]
public IKernal kernal { get; set; }
public T Resolve<T>(string type)
{
return kernal.TryGet<T>(type);
}
}
Step 3 Create an instance of your class
IFeature feature = null;
switch (typeOfFeature)
{
case Feature.SomeFeature:
feature = Resolver.TryResolve<IFeature>(nameof(SomeFeature));
break;
case Feature.OtherFeature:
feature = Resolver.TryResolve<IFeature>(nameof(OtherFeature));
break;
default:
throw new Exception("Type not supported");
}
return feature;
I am using unity mvc4 package, it is auto injecting into my controllers fine. But now I am manually doing other parts of my application, helpers etc.
How can I access the singletons within the container from other classes?
How do I call MethodWithDependency(param) on my instance of MyClass2? Am I supposed to do the below? It looks far too messy.
public class MyClass1
{
public void Main()
{
var myObject2 = container.Resolve<MyClass2>;
var someObject = container.Resolve<SomeClass>;
myObject2.MethodWithDependency(someObject);
}
}
public class MyClass2
{
public void MethodWithDependency(SomeClass someObject)
{
}
}
Each object that needs its dependencies resolved can potentially have them resolved by the container. To not to spoil your code with containers, you create local factories and implement specific factory providers elsewhere, in the Composition Root which is the only place in your application where container is created and used directly.
This requires discipline, however you are able to structure your code so that there is no explicit reference to the container except for the Composition Root and still container does the job.
I wrote a tutorial on that once, it is too long to quote it here:
http://www.wiktorzychla.com/2012/12/di-factories-and-composition-root.html
Answering your specific question: to have singletons you just use the ContainerControllerLifetimeManager as the parameter to the register method.
http://msdn.microsoft.com/en-us/library/ff660872(v=pandp.20).aspx
Create MyClass2 so that it accepts SomeClass as an argument in the constructor (you are injecting the SomeClass dependency into your MyClass2 object).
Then, you can register your Instances with the Container. At that point, when you resolve your MyClass2 object, your SomeClass object will also be resolved and injected into MyClass2.
Beautiful, huh?
The Code
public class MyClass1
{
private UnityContainer _container;
public void Main()
{
this.RegisterContainer();
// Since SomeClass was registered, when you resolve MyClass2, it will
// magically resolve an instance of SomeClass that the MyClass2
// constructor needs.
var myObject2 = this._container.Resolve<MyClass2>;
myObject2.MethodWithDependency();
}
private void RegisterContainer()
{
// Here, initialize your Container then register your singletons.
this._container = new UnityContainer();
// Do not use container.RegisterType<>()....
// RegisterInstance, by default, implements a singleton behavior.
this._container.RegisterInstance<SomeClass>();
this._container.RegisterInstance<MyClass2>();
}
}
public class MyClass2
{
private SomeClass _someClass;
// You are injecting the SomeClass dependency into your MyClass2 class.
// Hence the name — Dependency Injection.
public MyClass2(SomeClass someClass)
{
this._someClass = someClass;
}
public void MethodWithDependency()
{
// use your _someClass object.
this._someClass.DoSomething();
}
}