I am currently in the process of designing a new message translation system at work and have the following question concerning DI and Unity.
I have the following interface:
public interface ITranslate<TInput, TOutput>
{
TOutput TranslateMessage(TInput message);
}
With a concrete implementation of below (where InternalMessage is a custom class I have developed)
public class TestTranslate : ITranslate<byte[], InternalMessage>
{
InternalMessage Translate(byte[] message)
{
// Do the translation here and return the result....
}
}
However I want to using unity inject a translator instance into my Translator service through the constructor. To be used in a method within the service.
public class TranslatorService
{
private readonly ITranslator translator;
public TranslatorService(ITranslate translator)
{
this.translator = translator;
}
public byte[] DoTranslate(string message)
{
return translator.TranslateMessage(message);
}
}
However I have 2 questions:
1) Is it possible to have the ITranslate in the constructor without specifiying the types that the translator will deal with (I am trying to keep the Service
and Translator as generic as possible, so if another translation was needed I would only need to swap out the Concrete implementation of the Translator interface).
2) If this is possible how would I do it and then what would I have in my unity configuration to do that. Note I am using the XML configuration (not my choice) to
configure my dependenciues etc.
Thanks In Advance
Stuart
After some thinking, I assume you want to do the following:
At some point, messages of different types come in and have to be
translated to other types, somehow.
The component/client that receives these messages is and should be unaware of how different types of messages should be translated.
Therefore, you want to implement a generic TranslatorService-class that takes any message and magically translates is to the correct type, based on the input-message.
For each specific translation, you want to define a specific, generic Translator-class that is automatically instantiated and used by the TranslatorService-class, preferrably using dependency injection of some sort.
If my assumptions are correct, I would advise the following design.
First of all, define a generic interface that must be implemented by each specialized Translator-class. Only make the input-type generic:
interface IMessageTranslator<TMessage>
{
object Translate(TMessage message);
}
Then create the TranslatorService such that clients can just push in arbitrary messages and gives them back the result, if and only if a Translator for that message exists:
class TranslatorService
{
object Translate(object message)
{
}
}
Now the TranslatorService has to instantiate the correct IMessageTranslator<T> based on the type of message. You can do this with Unity by having the TranslatorService-class encapsulate a container that contains all IMessageTranslator<T>-types that you have implemented and then simply instantiate one based on the message type:
class TranslatorService
{
private readonly IUnityContainer _container;
public TranslatorService()
{
_container = new UnityContainer();
_container.RegisterType(typeof(IMessageTranslator<A>), typeof(MessageTranslatorA));
_container.RegisterType(typeof(IMessageTranslator<B>), typeof(MessageTranslatorB));
// Etc...
}
object Translate(object message)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
var genericTranslatorDefinition = typeof(IMessageTranslator<>);
var translatorType = genericTranslatorDefinition.MakeGenericType(message.GetType());
var translator = _container.Resolve(translatorType);
var translateMethod = translatorType.GetMethod("Translate", new [] { message.GetType() });
return translateMethod.Invoke(translator, new object[] { message });
}
}
Note that this is a naive implementation as to whether a translator actually exists/is registered for the specified message, and also in the way it finds the Translate-method (better to get it through the InterfaceMap), but you get the idea.
If you want even more flexibility, you could create a mechanism that auto-fills your container by scanning the assembly for IMessageTranslator-implementors. That way, you just add a new implementation and you're ready to go.
Related
I want to use Autofac to create a new instance of one or several WCF channels for a given unit of work. I'd like to use the command pattern to represent units of work, i.e. a given command class is injected with the channel(s) it needs and implements a bunch of related operations.
I tried the following:
interface IUnitOfWork
{
}
class FooCall : IUnitOfWork
{
readonly BarChannel _channel;
public FooCall(BarChannel channel)
{
Console.WriteLine($"FooCall({new {channel}})");
_channel = channel;
}
public string Foo()
{
return "FOO";
}
}
class BarChannel
{
public BarChannel()
{
Console.WriteLine("BarChannel()");
}
}
class FooService
{
Func<Owned<FooCall>> _helperFn;
public FooService(Func<Owned<FooCall>> helperFn)
{
_helperFn = helperFn;
}
public void CallFoo()
{
using (var helper = _helperFn())
{
Console.WriteLine($"CallFoo(), helper={helper}");
helper.Value.Foo();
}
}
}
class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<BarChannel>().InstancePerOwned<IUnitOfWork>();
builder.RegisterType<FooCall>().AsImplementedInterfaces().AsSelf();
builder.RegisterType<FooService>();
using (var scope = builder.Build().BeginLifetimeScope())
{
Console.WriteLine("call 1");
scope.Resolve<FooService>().CallFoo();
Console.WriteLine("call 2");
scope.Resolve<FooService>().CallFoo();
}
}
}
In short: a service method creates an owned unit of work; the unit of work is injected with a per-owned channel that it calls. The code sample should show two channel instances being created.
Except that it seems that the lifetime scope created for owned dependencies is only tagged with the type as which the dependency was resolved - i.e. as FooCall, not as IUnitOfWork. If I register BarChannel as InstancePerOwned<FooCall>, the code works; as is, registered as InstancePerOwned<IUnitOfWork>, it fails to resolve FooService since it can't find a matching lifetime scope. Am I missing something or is what I want to do not possible with Autofac? I'd rather not have to register all my WCF channels as instance-per-owned for every command class, that seems like it would get pretty verbose. Another workaround would be using instance-per-depedency and resolving a Func directly, but that won't let me say compose units of work while reusing channels and their dependencies between them.
The problem is that InstancePerOwned<T> is really just a special case of InstancePerMatchingLifetimeScope(params object[] lifetimeScopeTag), where the scope is tagged with something like typeof(T). As it stands, there needs to be a direct link between the tag provided there and the one attached to the scope when attempting to resolve, which is always set to the type of whatever's inside that specific Owned<> dependency. There's no additional logic to imply relations between types at that point, it's just a direct match on the tags.
However, InstancePerMatchingLifetimeScope does allow multiple tags to be specified, so it's possible to do something like:
builder.RegisterType<BarChannel>()
.InstancePerMatchingLifetimeScope(new TypedService(typeof(FooCall)),new TypedService(typeof(AnotherUnitOfWork)));
To wrap this up a bit more neatly you could use:
private static IEnumerable<Type> GetTypesImplementingInterface<TInterface>()
{
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => typeof(TInterface).IsAssignableFrom(p));
}
and then a new extension method:
public static class AutofacRegistrationBuilderExtensions
{
public static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> InstancePerOwned<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> builder, IEnumerable<Type> serviceTypes)
{
return builder.InstancePerMatchingLifetimeScope(serviceTypes.Select(s => new TypedService(s)).ToArray());
}
}
The usage would then just be:
builder.RegisterType<BarChannel>().InstancePerOwned(GetTypesImplementingInterface<IUnitOfWork>());
I'm not sure if the last part there would be worth pulling into Autofac itself, but I guess if it did then it might be better to combine the two methods above together and retrieve the list of types applicable from existing registrations, e.g. something like
InstancePerOwnedImplementing<TInterface>();
Alternatively, it would probably be a bit messy to extend the matching scope logic to check the relationship between types at resolution time, since not all tags are of the type Type.
I have a (growing) list of Data-Generators. The generator that I need is created by a factory class. The generators all implement a common Interface, which includes among other things a static string name.
What I would like to do: Call the factory.Create method with a string parameter for the above mentioned name. The create method finds the generator with this name and returns a new instance of said generator.
Bonus in my opinion of this way to do it: I only have to add new generator classes without having to edit the factory.
Question:
Is this a good way to handle this problem?
How can I find all generators? Reflection over every implementation of the interface/every member of the namespace (unique for the generators + their interface)?
Is it correct to call this way of working a factory, or is this some different pattern?
In the end I would call the factory like this (simplified):
//Caller
public DataModel GetData2()
{
var generator = new DataFactory().Create("Gen.2");
return generator.GetData();
}
//Factory
public class DataFactory
{
public AbstractDataGenerator Create(string type)
{
//Here the magic happens to find all implementations of IDataGenerator
var allGenerators = GetImplementations();
var generator = allGenerators.FirstOrDefault(f => f.name == type);
if (generator != null)
return (AbstractDataGenerator)Activator.CreateInstance(generator);
else
return null;
}
}
//Interface
public abstract class AbstractDataGenerator
{
public static string name;
public abstract DataModel GetData();
}
//Data-Generators
public class DataGen1 : AbstractDataGenerator
{
public static string name = "Gen.1";
public DataModel GetData()
{
return new DataModel("1");
}
}
public class DataGen2 : AbstractDataGenerator
{
public static string name = "Gen.2";
public DataModel GetData()
{
return new DataModel("2");
}
}
Should the magic GetImplementations() in the factory be done via Reflection or somehow different? Should I use a completely different approach?
Since answers refer to IoC and DI: This project uses NInject already, so it would be available.
Switched from interface to abstract class.
Is this a good way to handle this problem?
Having a factory to get an instance of the logic class you need by some key - I believe it is a good way. It is a pattern that I use a lot myself. About the way you have your key - I'd prefer to not have it as a static member (regardless to the fact that interfaces can't have static members) but just as a property and to add a base class to the IDataGenerator. That base class will have a constructor that will get the name - That way each new DataGenerator you create will have to set it and you wont forget.
About having the name as a string - I personally prefer having it "strongly typed". What I mean is that if I pass Gen . 2 instead of Gen.2 with strings I will discover this problem only in runtime. Possible other ways (if you want, because a simple string is fine too - a matter of taste):
Replace strings with an enum
Have a static class with static readonly strings for all your values - then in your code use those values. You get the benifits of the intellisense and of not getting the string wrong but better than enum - you can just still pass strings that are not in the "list" so you can add new ones as add-ons.
Have a RequestGenerator object, with each Generator being IDataGenerator<TGeneratorRequest>. This might be an overkill but if you have also extra information you need for the creating of a DataGenerator which differs between them then consider it .
How can I find all generators? Reflection over every implementation of the interface/every member of the namespace (unique for the generators + their interface)?
Yes, reflection can be a good way to do so. However, I would suggest to read into Dependency Injection and IoC Containers like Castle Windsor for example. There are things out there that already implement it for you, so why to re-invent the wheel :)
DI is a life changer concept in my opinion
Is it correct to call this way of working a factory, or is this some different pattern?
Yap. It is a Factory
Should the magic GetImplementations() in the factory be done via Reflection or somehow different?
See answer for question 2
This is where constructor injection can REALLY shine. Look into dependency injection tools and employ one! It also checks your "Bonus" request.
Here's what your factory might look like with constructor injection:
public class DataFactory
{
private Dictionary<string, IDataGenerator> generators;
public DataFactory(IDataGenerator[] generatorReferences)
{
this.generators = generatorReferences
.ToDictionary(k => k.name, v => v);
}
public IDataGenerator Create(string type)
{
IDataGenerator generator = null;
this.generators.TryGetValue(type, out generator);
return generator;
}
}
Most DI software has the capability to automatically scan assemblies for implementations of a certain type (e.g. IDataGenerator) and register those with itself, when it constructs an instance of your DataFactory it'll automatically include them.
I have this code:
using (container.BeginLifetimeScope())
{
RenderWord instruction = new RenderWord();
var instances = container.GetAllInstances<IInstructionHandler<RenderWord>>();
var firstInstance = result.First();
}
instances is of type IEnumerable<IInstructionHandler<RenderWord>>
firstInstance is of type IInstructionHandler<RenderWord> that in reality is an instance of a decorator that decorates another decorator that decorates another decorator ...
At runtime the actual class instances is of type ContainerControlledCollection<IInstructionHandler<RenderWord>> and this ContainerControlledCollection class holds a very useful piece of information - the underlying ImplementationType.
Is there any way for me to get to the ContainerControlledCollection or the producers[0].Value.ImplementationType at runtime because I’d really like to be able to discover the base implementation type underneath the chain of decorators.
I think #atomaras might have a good point about your abstraction, although I think it would be fine when you only use this information inside your Composition Root, since your Composition Root is already aware of every implementation in the system.
I think there are a few ways to get to this information:
Use the DecoratorPredicateContext information that is supplied to the RegisterDecorator extension method:
var typeMapping = new Dictionary<Type, Type>();
container.RegisterDecorator(typeof(IInstructionHandler<>), typeof(FakeDecorator<>), c =>
{
typeMapping[c.ServiceType] = c.ImplementationType;
// or perhaps even use c.AppliedDecorators property to see which decorators
// are applied.
// return false to prevent the decorator from being applied.
return false;
});
You can make a fake registration that Simple Injector will call for every IInstructionHandler<T> in the system, but you prevent it from being applied by supplying a predicate that will always return false. You can use the info supplied by Simple Injector in the DecoratorPredicateContext to find out what the actual ImplementationType is.
Alternatively, you can inject an DecoratorContext instance (v2.6 and up) into the top most decorator (as explained here). The DecoratorContext contains the same information as the DecoratorPredicateContext does, but this object will automatically be injected by Simple Injector into a decorator that depends on. It allows you to make the decision inside a decorator, which might be very convenient in your case.
Add an an IDecorator abstraction to the system to allow traversing the decorator chain.
By letting each decorator implement a IDecorator interface that allows access to the decoratee (just as done here) you can traverse the decorator chain and find the actual implementation type:
public interface IDecorator
{
object Decoratee { get; }
}
public static class DecoratorHelpers
{
public static IEnumerable<object> GetDecoratorChain(IDecorator decorator)
{
while (decorator != null)
{
yield return decorator;
decorator = decorator.Decoratee as IDecorator;
}
}
}
You can implement your decorators with this interface as follows:
public class SomeDecorator<T> : IInstructionHandler<T>, IDecorator
{
private readonly IInstructionHandler<T> decoratee;
public SomeDecorator(IInstructionHandler<T> decoratee)
{
this.decoratee = decoratee;
}
object IDecorator.Decoratee { get { return this.decoratee; } }
}
When you implemented this interface on all your decorators, you will be able to do this:
var implementationTypes =
from handler in container.GetAllInstances<IInstructionHandler<RenderWord>>()
let mostInnerDecorator =
DecoratorHelpers.GetDecoratorChain(handler as IDecorator).LastOrDefault()
let implementation = mostInnerDecorator != null ? mostInnerDecorator.Decoratee : handler
select implementation.GetType()
Register a list of Registration instances in one of the RegisterAll overloads, since the Registration object knows about the actual implemenation type.
But instead of point 3, you might as well use the list of implemenation types that you used to create those registrations:
typeMapping[serviceType] = implementationTypes;
container.RegisterAll(serviceType, implementationTypes);
Simple Injector will resolve the registered implementations always in the same order as they are registered (this is guaranteed). So when you resolve a collection of things, you will already have the list of implementations that is layed out in the same order.
Why dont you just check the type of the firstInstance? Wouldn't that give you the actual implementation type?
I have to say though that the fact that you need to know the implementation type is a good indication of problems with your abstraction.
I am in the process of refactoring a rather large portion of spaghetti code. In a nutshell it is a big "God-like" class that branches into two different processes depending in some condition. Both processes are lengthy and have lots of duplicated code.
So my first effort has been to extract those two processes into their own classes and putting the common code in a parent they both inherit from.
It looks something like this:
public class ExportProcess
{
public ExportClass(IExportDataProvider dataProvider, IExporterFactory exporterFactory)
{
_dataProvider = dataProvider;
_exporterFactory = exporterFactory;
}
public void DoExport(SomeDataStructure someDataStructure)
{
_dataProvider.Load(someDataStructure.Id);
var exporter = _exporterFactory.Create(_dataProvider, someDataStructure);
exporter.Export();
}
}
I am an avid reader of Mark Seemann's blog and in this entry he explains that this code has a temporal coupling smell since it is necessary to call the Load method on the data provider before it is in a usable state.
Based on that, and since the object is being injected to the ones returned by the factory anyway, I am thinking of changing the factory to do this:
public IExporter Create(IExportDataProvider dataProvider, SomeDataStructure someDataStructure)
{
dataProvider.Load(someDataStructure.Id);
if(dataProvider.IsNewExport)
{
return new NewExportExporter(dataProvider, someDataStructure);
}
return new UpdateExportExporter(dataProvider, someDataStructure);
}
Because of the name "DataProvider" you probably guessed that the Load method is actually doing a database access.
Something tells me an object doing a database access inside the create method of an abstract factory is not a good design.
Are there any guidelines, best practices or something that say this is effectively a bad idea?
Thanks for your help.
Typically, a factory is used to resolve concrete types of a requested interface or abstract type, so you can decouple consumers from implementation. So usually a factory is just going to discover or specify the concrete type, help resolve dependencies, and instantiate the concrete type and return it. However, there's no hard or fast rule as to what it can or can't do, but it is sensible to give it enough access to only to resources that it needs to resolve and instantiate concrete types.
Another good use of a factory is to hide from consumers types dependencies that are not relevant to the consumer. For example, it seems IExportDataProvider is only relevant internally, and can be abstracted away from consumers (such as ExportProcess).
One code smell in your example, however, is how IExportDataProvider is used. The way it currently seems to work, you get an instance of it once, but it's possible to change its state in subsequent usages (by calling Load). This can lead to issues with concurrency and corrupted state. Since I don't know what that type does or how it's actually used by your IExporter, it's hard to make a recommendation. In my example below, I make an adjustment so that we can assume that the provider is stateless, and instead Load returns some sort of state object that the factory can use to resolve the concrete type of exporter, and then provide data to it. You can adjust that as you see fit. On the other hand, if the provider has to be stateful, you'll want to create an IExportDataProviderFactory, use it in your exporter factory, and create a new instance of the provider from the factory for each call to exporter factory's Create.
public interface IExporterFactory
{
IExporter Create(SomeDataStructure someData);
}
public class MyConcreteExporterFactory : IExporterFactory
{
public MyConcreteExporterFactory(IExportDataProvider provider)
{
if (provider == null) throw new ArgumentNullException();
Provider = provider;
}
public IExportDataProvider Provider { get; private set; }
public IExporter Create(SomeDataStructure someData)
{
var providerData = Provider.Load(someData.Id);
// do whatever. for example...
return providerData.IsNewExport ? new NewExportExporter(providerData, someData) : new UpdateExportExporter(providerData, someData);
}
}
And then consume:
public class ExportProcess
{
public ExportProcess(IExporterFactory exporterFactory)
{
if (exporterFactory == null) throw new ArgumentNullException();
_exporterFactory = factory;
}
private IExporterFactory _exporterFactory;
public void DoExport(SomeDataStructure someData)
{
var exporter = _exporterFactory.Create(someData);
// etc.
}
}
I'm writing some tests, and frequently I find myself having to look up generic parameters to pass explicitly pass along.
public class MyService : SecureService<RootEntity>
{
//Intentionally omitted does not provide information related to question
}
public DepedencyReplaceScope<IContextProvider> CreateMockScope<TRootEntity>
{
var mockCtx = Mock.Of<IContextProvider>(x => x.WriteContext<TRootEntity> == new FakeContext<TRootEntity>())
return new DependencyReplaceScope(mockCtx);
}
Currently when I'm creating mocks for my test, I have too go into the service and find out what it's root is to pass along. However, It would be a lot nicer if I could create a scope based on the service.
e.g (pseudo code)
public DepedencyReplaceScope<IContextProvider> CreateMockScopeFromService<TService>
where TService : SecureService<>
define TRootEntity : TService<()>
{
return CreateMockScope<TRootEntity>();
}
This won't work since I don't think there is a way to define a proxy for the Generic. Is there a way to create this scope solely from the TService (I don't want to use reflection directly to build it, but I don't mind using a hack with a moq since it abstracts the reflection)
The best thing I was able to come up so far was:
public static class MockScopeProvider
{
public static DepedencyReplaceScope<IContextProvider> CreateMockScopeFromService<U>(SecureService<U> dummy)
{
// your logic....
var mockCtx = Mock.Of<IContextProvider>(x => x.WriteContext<U>() == new FakeContext<U>());
return new DependencyReplaceScope(mockCtx);
}
}
With usage being like that:
MockScopeProvider.CreateMockScopeFromService(default(MyService));