I'm still new to using Autofac and I'm bothered by the constructor injection method that I'm using. Here's the scenario:
I currently have two classes which inherits the IForms interface. Each of the classes has its own interface as well
public interface IForms
{
long CreateNewForm(FormData data);
FormData RetrieveFormById(long id);
}
public interface IFormA : IForms
{ }
public interface IFormB : IForms
{ }
Now I have a class which handles this which is like this:
public class ApplicationForms : IApplicationForms
{
private readonly IFormA _formA;
private readonly IFormB _formB;
public ApplicationForms(IFormA formA, IFormB formB)
{
_formA = formA;
_formB = formB;
}
public void SubmitApplicationForm(FormData data)
{
switch(data.FormType)
{
case FormType.FormA:
_formA.CreateNewForm(data);
break;
case FormType.FormB:
_formB.CreateNewForm(data);
break;
}
}
}
Now there's a possibility that there will be 2 more forms coming in (ex. FormC, FormD, FormE). What will happen here is that there will be 3 more constructor parameters in the ApplicationForms constructor.
Is there a way to like combine all the constructor parameters into one parameter? I can see that it will definitely look ugly in the end.
The problem you're describing is that you have many forms, but at runtime you need one specific form, and so you don't want to inject all of the forms. That might be a good scenario for an abstract factory.
We often represent the factory as an interface with a single method, but we can also do it with a delegate:
public delegate IForm GetFormByTypeFunction(FormType formType);
Now your class looks like this:
public class ApplicationForms : IApplicationForms
{
private readonly GetFormByTypeFunction _getFormByType;
public ApplicationForms(GetFormByTypeFunction getFormByType)
{
_getFormByType = getFormByType;
}
public void SubmitApplicationForm(FormData data)
{
var form = _getFormByType(data.FormType);
form.CreateNewForm(data);
}
}
Now the question is how to implement the factory. It might still have a switch statement or something that doesn't seem too elegant, but that's okay. The point of the factory is that however it works, the business of creating and/or selecting an implementation is moved out of the class that depends on the implementation.
You can register a delegate with Autofac like this:
builder.Register<GetFormByTypeFunction>(context => formType =>
{
switch (formType)
{
case FormType.Type1:
{
return context.Resolve<FormOne>();
}
case FormType.Type2:
{
return context.Resolve<FormTwo>();
}
default:
throw new InvalidOperationException("Unknown form type");
}
});
Now you don't need to resolve all of the IForm implementations up front because you can resolve the one you want directly from the container once you know which one you want.
That might seem "wrong" because you're resolving from the container. But you're not resolving directly from the container. You're depending on a factory. That factory can be replaced with any other implementation which means that your class does not depend on the container.
This sort of factory is also super easy to mock. Technically it's not even a mock. It's just an implementation of the factory that returns a mock.
var formMock = new Mock<IForm>();
var factory = new GetFormByTypeFunction(formType => formMock.Object);
Since there is a common IForms interface, then you can inject an enumeration.
This looks like a good candidate for strategy pattern.
I would suggest refactoring the base interface to be able to identify what type of form it is
public interface IForms {
FormType FormType { get; }
long CreateNewForm(FormData data);
FormData RetrieveFormById(long id);
}
and update the dependent class
public class ApplicationForms : IApplicationForms {
private readonly IEnumerable<IForms> forms;
public ApplicationForms(IEnumerable<IForms> forms) {
this.forms = forms;
}
public void SubmitApplicationForm(FormData data) {
var form = forms.FirstOrDefault(_ => _.FormType == data.FormType);
if(form != null)
form.CreateNewForm(data);
//...
}
}
This assumes that when registering the derived interfaces that you associate it with the base IForms interface.
var builder = new ContainerBuilder();
builder.RegisterType<FormA>().As<IForms>();
builder.RegisterType<FormB>().As<IForms>();
builder.RegisterType<FormC>().As<IForms>();
//...
Now no matter how many more forms are added the class can perform without modification.
Related
I'm trying to register by convention multiple implementation of single interface and later use all those interfaces as dependency in other classes. Unfortunatelly, I'm having some problems trying to do so.
I want to register multiple implementation, so I added WithName.TypeName druing registration but this seems to be causing problems. Without it, I can't register multiple implementations for single interface.
Below is simple example which is not working. Unity is throwing exception and I don't know why.
Unity.ResolutionFailedException: 'Resolution failed with error: No
public constructor is available for type KYPClient.IConf.
namespace KYPClient
{
public interface IConf
{
string conf();
}
public class Conf : IConf
{
public string conf()
{
return "conf";
}
}
public interface ILoader
{
string load();
}
public class Load_1 : ILoader
{
public string load()
{
return "load-1";
}
}
public class Load_2 : ILoader
{
public string load()
{
return "load-2";
}
}
public class MainCls
{
private IConf _conf;
private IEnumerable<ILoader> _loaders;
public MainCls(IConf conf, IEnumerable<ILoader> loaders)
{
_conf = conf;
_loaders = loaders;
}
public void Run()
{
System.Console.WriteLine(_conf.conf());
foreach (var l in _loaders)
{
Console.WriteLine(l.load());
}
}
}
internal static class Client
{
private static void Main()
{
using var container = new UnityContainer();
container.RegisterTypes(
AllClasses.FromAssemblies(typeof(MainCls).Assembly),
WithMappings.FromAllInterfaces,
WithName.TypeName,
WithLifetime.ContainerControlled);
var main = container.Resolve<MainCls>();
main.Run();
}
}
}
The issue is you're using the WithName.TypeName option. This means that each type from the assembly is done as a named registration in the container. This is a good thing in your case because you are registering multiple ILoader instances, so the container has to be able to differentiate them. However, it also means that when it's being resolved, you have to pass the name in order for the container to find it.
In other words, when the container sees the constructor public MainCls(IConf conf, IEnumerable<ILoader> loaders) it interprets that as "inject the IConf instance with the default name" which doesn't exist in your container. Your IConf is registered with the name "Conf" (or possibly "KYPClient.Conf", I'm not sure, as I've never used the RegisterTypes method).
Thus, you have to explicitly name it in your constructor. Also, per How to configure Unity to inject an array for IEnumerable you need an array to get all the registered ILoader types.
public MainCls([Dependency("Conf")] IConf conf, ILoader[] loaders)
Of course, there are some drawbacks to using named dependencies (such as, what happens if you refactor and rename your class). Take a look at the second answer to With Unity how do I inject a named dependency into a constructor? for a strategy around that using a factory pattern.
I have several Get____Factory methods in my application and I'd like to consolidate them with generics, but I'm still adjusting C# and a) am not 100% sure generics are the right way to go and b) am still learning how C# handles generics.
I'll eventually have a dictionary/map of factory interfaces and their classes. Not only do I want to consolidate all of my factories into an easy-access method but I need to allow plugin authors a way to register their own (and have access to them this way).
I started with something like this:
Note: Eventually there will be a dictionary or way to map interfaces types to their implementations - the if/else conditions are ugly and temporary, but simply a way to test.
public T GetFactory<T>() where T : IFactory {
var t = typeof(T);
if (t.Equals(typeof(IRecipeFactory))) {
var factory = new RecipeFactory();
return factory;
}
else if (t.Equals(typeof(IItemFactory))) {
var factory = new ItemFactory();
return factory;
}
else if (t.Equals(typeof(ITileFactory))) {
var factory = new TileFactory();
return factory;
}
}
It fails with Cannot implicitly convert type 'RecipeFactory' to 'T', so this won't work. In the long run I won't have conditionals but will rather lookup the class by its type. However, neither will work until I can find a solution for the cast issue.
Based on other answers, I tried double-casting ((T) (object)) but that errors with InvalidCastException: Cannot cast from source type to destination type..
Either this is a poor architecture or I'm using the generics incorrectly.
Here is solution bit different from S.C.'s solution.
public static class FactoryService
{
private static readonly Dictionary<Type, Func<IFactory>> factories = new Dictionary<Type, Func<IFactory>>()
{
{ typeof(IRecipeFactory), () => new RecipeFactory() },
{ typeof(IItemFactory), () => new ItemFactory() },
{ typeof(ITileFactory), () => new TileFactory() }
};
public static T GetFactory<T>() where T : IFactory
{
T factory = default(T);
Type requestedType = typeof(T);
if (factories.ContainsKey(requestedType))
{
factory = (T)factories[requestedType].Invoke();
}
return factory;
}
}
public interface IFactory { }
public interface IRecipeFactory : IFactory { }
public interface IItemFactory : IFactory { }
public interface ITileFactory : IFactory { }
public class RecipeFactory : IRecipeFactory { }
public class ItemFactory : IItemFactory { }
public class TileFactory : ITileFactory { }
Then you use it like this:
IRecipeFactory rf = FactoryService.GetFactory<IRecipeFactory>();
Let me first say that you are actually looking at is a simple version of an Inversion of Control (IOC) framework. Take a look at Ninject or something similar because it's kernel and binding factory are pretty much exactly what you want. It even allows the attachment of metadata so you can have the same interface resolve to different implementations depending on the circumstances, which is really useful when you have a data layer that might need to pull from either a web data source or a cache data source, for instance. Most IOC frameworks also offer recursive dependency resolution, which means when some instances have constructors that require other dependencies, the same dependency resolution occurs all the way down the chain based on the mappings or default mappings that can be inferred.
Aside from that, to do what you're after yourself, you'll want to make use of Activator.CreateInstance which takes a type and will construct a new instance based on that. You are on the right track with your dictionary mappings. When you tie those two together, you don't need any conditional logic and you don't need to know ahead of time or care about what type is being requested. When you're feeling comfortable you can actually shorten the dependency resolution and instantiation to a single line if you wish.
Here is a fully working sample (from my 30 seconds of testing) that does what you want to to the best of my understanding:
using System;
using System.Collections.Generic;
namespace Generics
{
// create some dummy interfaces and implementations.
// make sure everything inherits from the same type to allow for
// a generic return statement
public interface IFactory
{
void DoStuff();
}
public interface IFactory1 : IFactory { }
public class Factory1 : IFactory1
{
public void DoStuff()
{
Console.WriteLine("Factory1");
}
}
public interface IFactory2 : IFactory { }
public class Factory2 : IFactory2
{
public void DoStuff()
{
Console.WriteLine("Factory2");
}
}
class Program
{
// create our binding mappings
IDictionary<Type, Type> bindings = new Dictionary<Type, Type>()
{
// expose a way for plugins/etc to add to this. that part is trivial.
{typeof(IFactory1), typeof(Factory1) },
{typeof(IFactory2), typeof(Factory2) }
};
// a method to actually resolve bindings based on expected types
public IFactory ResolveBinding<T>() where T : IFactory
{
Type requestedType = typeof(T);
if (requestedType != null && bindings.ContainsKey(requestedType))
{
// use the activator to generically create an instance
return (T) Activator.CreateInstance(bindings[requestedType]);
}
return null;
}
// test it out
static void Main(string[] args)
{
Program demo = new Program();
// test with two interfaces
demo.ResolveBinding<IFactory1>().DoStuff(); // prints out "Factory1"
demo.ResolveBinding<IFactory2>().DoStuff(); // prints out "Factory2"
Console.ReadKey();
}
}
}
You are going to want to cast the object to T on the way out since the method returns T. To do this cast you will have to make factory an IFactory
public T GetFactory<T>() where T : IFactory
{
var t = typeof(T);
if (t.Equals(typeof(IRecipeFactory)))
{
IFactory factory = new RecipeFactory();
return (T)factory;
}
if (t.Equals(typeof(IItemFactory)))
{
IFactory factory = new ItemFactory();
return (T)factory;
}
if (t.Equals(typeof(ITileFactory)))
{
IFactory factory = new TileFactory();
return (T)factory;
}
throw new InvalidOperationException("Type not supported");
}
I just started to learn Decorator Design Pattern, unfortunately i had to go through various refrences to understand the Decorator pattern in a better manner which led me in great confusion. so, as far as my understanding is concern, i believe this is a decorator pattern
interface IComponent
{
void Operation();
}
class Component : IComponent
{
public void Operation()
{
Console.WriteLine("I am walking ");
}
}
class DecoratorA : IComponent
{
IComponent component;
public DecoratorA(IComponent c)
{
component = c;
}
public void Operation()
{
component.Operation();
Console.WriteLine("in the rain");
}
}
class DecoratorB : IComponent
{
IComponent component;
public DecoratorB(IComponent c)
{
component = c;
}
public void Operation()
{
component.Operation();
Console.WriteLine("with an umbrella");
}
}
class Client
{
static void Main()
{
IComponent component = new Component();
component.Operation();
DecoratorA decoratorA = new DecoratorA(new Component());
component.Operation();
DecoratorB decoratorB = new DecoratorB(new Component());
component.Operation();
Console.Read();
}
}
But can the below code also be Decorator Pattern?
class Photo
{
public void Draw()
{
Console.WriteLine("draw a photo");
}
}
class BorderedPhoto : Photo
{
public void drawBorder()
{
Console.WriteLine("draw a border photo");
}
}
class FramePhoto : BorderedPhoto
{
public void frame()
{
Console.WriteLine("frame the photo");
}
}
class Client
{
static void Main()
{
Photo p = new Photo();
p.Draw();
BorderedPhoto b = new BorderedPhoto();
b.Draw();
b.drawBorder();
FramePhoto f = new FramePhoto();
f.Draw();
f.drawBorder();
f.frame();
}
}
My Understanding
From the second example given by me, we can call all the three methods, but from the first example i wont be able to get access to all the three methods by creating a single object.
It should be a comment, but I have too many words.
For example, you have an object and interface, like Repository : IRepository.
public interface IRepository
{
void SaveStuff();
}
public class Repository : IRepository
{
public void SaveStuff()
{
// save stuff
}
}
and client, which probably was written by someone else
class RepoClient
{
public void DoSomething(IRepository repo)
{
//...
repo.SaveStuff();
}
}
And once you decided, that ALL calls to repository should be logged. But you have a problem: the Repository class is from an external library and you don't want to change that code. So you need to extend the Repository's behavior that you use. You write RepositoryLogDecorator : IRepository, and inside on each method do the logging, like
public class RepositoryLogDecorator : IRepository
{
public IRepository _inner;
public RepositoryLogDecorator(IRepository inner)
{
_inner = inner;
}
public void SaveStuff()
{
// log enter to method
try
{
_inner.SaveStuff();
}
catch(Exception ex)
{
// log exception
}
// log exit to method
}
}
So, before you could use client as
var client = new RepoClient();
client.DoSomething(new Repository());
but now you can use
var client = new RepoClient();
client.DoSomething(new RepositoryLogDecorator(new Repository()));
Note, that this is a very simple example. In real projects, where object created primary with DI container, you will be able to use decorator by changing some config.
So, decorator is used to extend functionality of object without changing object or client.
Another benefit of decorator: your decorator does not depend on Repository implementation. Only depends from an interface IRepository. Why this is an advantage? If somehow you decide to write you own implementation of IRepository
public class MyAwesomeRepository : IRepository
{
public void SaveStuff()
{
// save stuff, but AWESOME!
}
}
you will be able to automatically decorate this with decorator, which already exist
var client = new RepoClient();
client.DoSomethig(new RepositoryLogDecorator(new MyAwesomeRepository()));
Want to see example from real software? (just as sample, code is ugly, I know) => go here
There is this PatternCraft series on Youtube that explains Design Patterns with Starcraft, you should check the video about Decorators here.
In the video above the author gives an example with a Marine and WeaponUpgrade.
In the game you will have a Marine and then you can upgrade its weapon:
marine = new WeaponUpgrade(marine);
Note that you still have a marine there, it is not a new unit, it is the same unit with things that modifies its attributes.
public class MarineWeaponUpgrade : IMarine
{
private IMarine marine;
public MarineWeaponUpgrade(IMarine marine)
{
this.marine = marine;
}
public int Damage
{
get { return this.marine.Damage + 1; } // here
set { this.marine.Damage = value; }
}
}
You do that by creating a class that implements the same interface as your unit and access your unit properties to modify values.
There is a Kata on CodeWars challenging you to complete the Weapon and Armor decorators for a marine.
Per GOF page Decorator desing pattern:
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
In your second example you are using inheritance to extend behaviour of a class, I believe this is technically not a Decorator design pattern.
The decorator pattern allows you to add a specific behavior to an individual object of a given type without affecting other instances of that same type.
In your second example, which is normal inheritance, all instances of the class inherit the modified behavior.
The second example is not a decorate pattern, since an essential ingredient to decorator pattern is that the object accepts one of its kind and possibly enhance it.
An instances of this in the first example is
public DecoratorA(IComponent c)
{
component = c;
}
Also, the goal of the decorator pattern is to create "one" object, then decorate it by passing it through different filters or decorators.
Hence the line
DecoratorA decoratorA = new DecoratorA(new Component());
Should be
DecoratorA decoratorA = new DecoratorA(component );
I am trying to implement the strategy pattern in my repository layer using SM and generics. For that I have an interface, IPocoRepository, which has a concrete implementation using Entity Framework. This I have managed to wire up in my Bootstrapper-file:
For(typeof(IPocoRepository<>)).Use(typeof(EntityFrameworkRepository<>));
The problem appears when I try to implement caching for this interface. In my cached class I want an instance of the base repository class, so that I can keep my design DRY. Let me outline how these three files look:
public interface IPocoRepository<T>
{
IQueryable<T> GetAll();
...
public class EntityFrameworkRepository<T> : IPocoRepository<T> where T : class
{
public IQueryable<T> GetAll()
{
...
public class CachedRepository<T> : IPocoRepository<T> where T : class
{
private IPocoRepository<T> _pocoRepository;
public CachedRepository(IPocoRepository<T> pr)
{
_pocoRepository = pr;
}
public IQueryable<T> GetAll()
{
var all = (IQueryable<T>)CacheProvider.Get(_cacheKey);
if (!CacheProvider.IsSet(_cacheKey))
{
all = _pocoRepository.GetAll();
...
Edit: I want StructureMap to return CachedRepository when IPocoRepository is requested, except when requested for in CachedRepository - then I want it to return EntityFrameworkRepository.
I know this is simple when dealing with non-generic classes:
For<ICountyRepository>().Use<CachedCountyRepository>()
.Ctor<ICountyRepository>().Is<CountyRepository>();
I tried searching the documentation for how to do this, but couldn't find anything. Any help would be appreciated!
Ok, this isn't too hard. You can use a type interceptor. Given you have the following classes:
public interface IRepository<T>{}
public class Repository<T>:IRepository<T>{}
public class RepositoryCache<T> : IRepository<T>
{
private readonly IRepository<T> _internalRepo;
public RepositoryCache(IRepository<T> internalRepo)
{
_internalRepo = internalRepo;
}
public IRepository<T> InternalRepo
{
get { return _internalRepo; }
}
}
You will then need to create a type interceptor. You can use the configurable "MatchedTypeInterceptor" provided by StructureMap for this. The interceptor will need to look for your repositories and then figure out what the generic type parameters are. Once it has the type parameters it can declare the type of cache it needs and initialize it. As part of the initialization, it will take the original repository in it's constructor. Then the interceptor will return the completed cache to whatever requested it from the ioc context. Here is the complete sequence inside a test.
This can be moved out into your registry, I just left it all together as an minimal example.
[Test]
public void doTest()
{
MatchedTypeInterceptor interceptor = new MatchedTypeInterceptor(
x => x.FindFirstInterfaceThatCloses(typeof (IRepository<>)) != null);
interceptor.InterceptWith(original =>
{
Type closedType = original.GetType()
.FindFirstInterfaceThatCloses(typeof(IRepository<>));
var genericParameters = closedType.GetGenericArguments();
var closedCacheType = typeof(RepositoryCache<>)
.MakeGenericType(genericParameters);
return Activator.CreateInstance(closedCacheType, new[] {original});
});
ObjectFactory.Initialize(x =>
{
x.For(typeof (IRepository<>)).Use(typeof (Repository<>));
x.RegisterInterceptor(interceptor);
});
var test = ObjectFactory.GetInstance<IRepository<int>>();
Assert.That(test is RepositoryCache<int>);
}
I'm implementing a factory pattern that looks as follows.
public class FeedFactory
{
#region Singleton Pattern
//..
#endregion
private static Feed[] _factory = new Feed[(int)FeedType.Total];
public void RegisterFeed(FeedType feedType,Feed feed)
{
if (_factory[(int)feedType] == null)
{
_factory[(int)feedType] = feed;
}
else
{
// already registered
}
}
public Feed GetFeed(FeedType feedType)
{
return _factory[(int)feedType];
}
}
Here, Feed is an abstract class from which the different classes inherit. How can I register the different classes? Is it possible to do it from their constructor?
This is not a factory pattern. A factory will always have some constructor logic in it, at least one new. That's the idea of a factory: the caller doesn't have to worry about how objects are created. This is a singleton repository.
So first of all, instead of using an array, you should be having a type indexed dictionary.
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
After that, you don't need a register method. The dictionary should be filled automatically when you retrieve singletons.
Now I suppose your Feed class has a default constructor without arguments. In that case, you can implement a factory method directly from the abstract class Feed. We're going to use some generics here, because it allows you to control inheritance:
public abstract class Feed
{
public static T GetInstance<T>() where T:Feed, new()
{
T instance = new T();
// TODO: Implement here other initializing behaviour
return instance;
}
}
Now back to your singleton repository.
public class FeedSingletonRepository
{
private static readonly object _padlock = new object();
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
public static T GetFeed<T>() where T:Feed
{
lock(_padlock)
{
if (!_singletons.ContainsKey(typeof(T))
{
_singletons[typeof(T)] = Feed.GetInstance<T>();
}
return (T)_singletons[typeof(T)];
}
}
}
Note that I included a threadsafe behaviour which is a good thing to do when you work with singletons.
Now if you want to get the singleton for a given type inheriting from Feed (let's call it SpecializedFeedType), all you have to do is:
var singleton = FeedSingletonRepository.GetFeed<SpecializedFeedType>();
or
SpecializedFeedType singleton = FeedSingletonRepository.GetFeed();
which is the same line with a slightly different syntax.
Edit2: changed some syntax errors.
Just as a side note -- as a factory is intended to wrap creation, it's a curious choice that you're creating objects and registering them with the factory. Is this more an object repository than a factory, or is there more to the class than I'm seeing?
If it is an object repository, then you might also find some extra inspiration in other questions, like this one.
When you call the RegisterFeed method you need to pass a concrete instance of a Feed class. So it is the responsibility of the caller to provide the concrete implementation.
Just register the type of the classes you want to create, then use Activator.CreateInstance to create instances of that type.
It should work this way:
private static Type[] _factory = new Type[(int)FeedType.Total];
public void RegisterFeed(FeedType feedType, Type type)
{
...
_factory[(int)feedType] = type;
...
}
public Feed GetFeed(FeedType feedType)
{
return Activator.CreateInstance(_factory[(int)feedType]) as Feed;
}
You can call RegisterFeed like the following:
RegisterFeed(FeedType.SomethingSpecial, typeof(MyDerivedSpecialFeed));
class FeedFactory {
public IFeedFactory GetFeedFactory(string type) {
switch(type) {
case "1": return new Feed1(); break;
case "2": return new Feed2(); break;
}
}
}
Note all Feeds Must implement an IFeedFactory interface and implement the method necessary.
//From the client
FeedFactory ff1 = new FeedFactory();
IFeedFactory obj = ff1.GetFeedFactory("1");
obj.ExecuteMethod();