Related
A brainteaser for you!
I am developing a modular system, in such a way that module A could need module B and module B could also need module A. But if module B is disabled, it will simply not execute that code and do nothing / return null.
A little bit more into perspective:
Let's say InvoiceBusinessLogic is within module "Core". We also have a "Ecommerce" module which has a OrderBusinessLogic. The InvoiceBusinessLogic could then look like this:
public class InvoiceBusinessLogic : IInvoiceBusinessLogic
{
private readonly IOrderBusinessLogic _orderBusinessLogic;
public InvoiceBusinessLogic(IOrderBusinessLogic orderBusinessLogic)
{
_orderBusinessLogic = orderBusinessLogic;
}
public void UpdateInvoicePaymentStatus(InvoiceModel invoice)
{
_orderBusinessLogic.UpdateOrderStatus(invoice.OrderId);
}
}
So what I want is: When the module "Ecommerce" is enabled, it would actually do something at the OrderBusinessLogic. When not, it would simply not do anything. In this example it returns nothing so it can simply do nothing, in other examples where something would be returned, it would return null.
Notes:
As you can probably tell, I am using Dependency Injection, it is a ASP.NET Core application so the IServiceCollection takes care of defining the implementations.
Simply not defining the implementation for IOrderBusinessLogic will cause a runtime issue, logically.
From a lot of research done, I do not want to make calls to the container within my domain / logic of the app. Don't call the DI Container, it'll call you
These kind of interactions between modules are kept to a minimum, preferably done within the controller, but sometimes you cannot get around it (and also in the controller I would then need a way to inject them and use them or not).
So there are 3 options that I figured out so far:
I never make calls from module "Core" to module "Ecommerce", in theory this sounds the best way, but in practice it's more complicated for advanced scenarios. Not an option
I could create a lot of fake implementations, depending on the configuration decide on which one to implement. But that would of course result in double code and I would constantly have to update the fake class when a new method is introduced. So not perfectly.
I can build up a fake implementation by using reflection and ExpandoObject, and just do nothing or return null when the particular method is called.
And the last option is what I am now after:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
return;
}
dynamic expendo = new ExpandoObject();
IOrderBusinessLogic fakeBusinessLogic = Impromptu.ActLike(expendo);
services.AddTransient<IOrderBusinessLogic>(x => fakeBusinessLogic);
}
By using Impromptu Interface, I am able to successfully create a fake implementation. But what I now need to solve is that the dynamic object also contains all the methods (mostly properties not needed), but those ones are easy to add. So currently I am able to run the code and get up until the point it will call the OrderBusinessLogic, then it will, logically, throw an exception that the method does not exist.
By using reflection, I can iterate over all the methods within the interface, but how do I add them to the dynamic object?
dynamic expendo = new ExpandoObject();
var dictionary = (IDictionary<string, object>)expendo;
var methods = typeof(IOrderBusinessLogic).GetMethods(BindingFlags.Public);
foreach (MethodInfo method in methods)
{
var parameters = method.GetParameters();
//insert magic here
}
Note: For now directly calling typeof(IOrderBusinessLogic), but later I would iterate over all the interfaces within a certain assembly.
Impromptu has an example as follows:
expando.Meth1 = Return<bool>.Arguments<int>(it => it > 5);
But of course I want this to be dynamic so how do I dynamically insert the return type and the parameters.
I do understand that a interface acts like a contract, and that contract should be followed, I also understand that this is an anti-pattern, but extensive research and negotiations have been done prior to reaching this point, for the result system we want, we think this is the best option, just a little missing piece :).
I have looked at this question, I am not really planning on leaving .dll's out, because most likely I would not be able to have any form of IOrderBusinessLogic usable within InvoiceBusinessLogic.
I have looked at this question, but I did not really understand how TypeBuilder could be used in my scenario
I have also looked into Mocking the interfaces, but mostly you would then need to define the 'mocking implementation' for each method that you want to change, correct me if I am wrong.
Even tough the third approach (with ExpandoObject) looks like a holy grail, I foster you to not follow this path for the following reasons:
What guarantees you that this fancy logic will be error-free now and at every time in the future ? (think: in 1 year you add a property in IOrderBusinessLogic)
What are the consequences if not ? Maybe an unexpected message will pop to the user or cause some strange "a priori unrelated" behavior
I would definitely go down the second option (fake implementation, also called Null-Object) even though, yes it will require to write some boilerplate code but ey this would offer you a compile-time guarantee that nothing unexpected will happen at rutime !
So my advice would be to do something like this:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
}
else
{
services.AddTransient<IOrderBusinessLogic, EmptyOrderBusinessLogic>();
}
}
For as long as there is no other answer for the solution I am looking for, I came up with the following extension:
using ImpromptuInterface.Build;
public static TInterface IsModuleEnabled<TInterface>(this TInterface obj) where TInterface : class
{
if (obj is ActLikeProxy)
{
return default(TInterface);//returns null
}
return obj;
}
And then use it like:
public void UpdateInvoicePaymentStatus(InvoiceModel invoice)
{
_orderBusinessLogic.IsModuleEnabled()?.UpdateOrderStatus(invoice.OrderId);
//just example stuff
int? orderId = _orderBusinessLogic.IsModuleEnabled()?.GetOrderIdForInvoiceId(invoice.InvoiceId);
}
And actually it has the advantage that it is clear (in the code) that the return type can be null or the method won't be called when the module is disabled. The only thing that should be documented carefully, or in another way enforced, that is has to be clear which classes do not belong to the current module. The only thing I could think of right now is by not including the using automatically, but use the full namespace or add summaries to the included _orderBusinessLogic, so when someone is using it, it is clear this belongs to another module, and a null check should be performed.
For those that are interested, here is the code to correctly add all fake implementations:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
return;
}
//just pick one interface in the correct assembly.
var types = Assembly.GetAssembly(typeof(IOrderBusinessLogic)).GetExportedTypes();
AddFakeImplementations(services, types);
}
using ImpromptuInterface;
private static void AddFakeImplementations(IServiceCollection services, Type[] types)
{
//filtering on public interfaces and my folder structure / naming convention
types = types.Where(x =>
x.IsInterface && x.IsPublic &&
(x.Namespace.Contains("BusinessLogic") || x.Namespace.Contains("Repositories"))).ToArray();
foreach (Type type in types)
{
dynamic expendo = new ExpandoObject();
var fakeImplementation = Impromptu.DynamicActLike(expendo, type);
services.AddTransient(type, x => fakeImplementation);
}
}
Having something like a string parameter in a constructor makes dependency injection very messy. Think:
public class CurrencyActor
{
public CurrencyActor(string currency, IRepository repository)
{
...
There have been other questions (such as this one) to address this particular problem with dependency injection. Often this is solved by rethinking the design and refactoring.
However, what if it actually makes sense to have multiple versions of an object that are each responsible for different data (e.g. a CurrencyActor for each currency)? This is pretty normal when using an actor model such as Akka .NET, but makes sense even outside that domain.
What is the best way to create these multiple instances using dependency injection while passing in the initial state they need?
Having a dependency in a constructor is not messy, it's very very common. There is nothing wrong with this.
You could create a default props static method on the CurrencyActor that takes in your dependencies:
public static Props CreateProps(string currency, Irepository repo)
{
return Props.Create(() => new CurrrncyActor(currency, repo));
}
Then create as many as you like:
var usCurrency = system.ActorOf(CurrencyActor.CreateProps("US", someRepo), "US");
var swedishCurrency = system.ActorOf(CurrencyActor.CreateProps("SEK", someRepo), "SEK");
[Update]
Regarding the use of DI containers with Akka, this was listed as no. 2 out of the top 7 mistakes people make when using akka.net
https://petabridge.com/blog/top-7-akkadotnet-stumbling-blocks/
Thus it’s considered to be a good practice for actors to manage their own dependencies, rather than delegate that work to a DI framework.
So basically don't do it. And if you must, according to that article, Autofac is the best choice
[Update 2]
If you want to dynamically create new instances of the same Actor but change some initial state, then you could have a Supervisor that is responsible for creating them:
public class MatchesSupervisor : ReceiveActor
{
List<IActorRef> _matches = new List<IActorRef>();
public void MatchesSupervisor()
{
Receive<SomeCommandToStartANewMatch>(msg =>
{
// store the currently active matches somewhere, maybe on a FullTime message they would get removed?
_matches.Add(Context.ActorOf(MatchActor.Create(msg.SomeMatchId)));
}
}
}
In the above example, there is no DI container being used, and if each MatchActor needed something else, like an IRepository, then this would be passed into the MatchesSupervisor when it is created, and subsequently passed to each MatchActor when they are created.
It also kinda depends where the state is coming from, and what the mechanism is for starting a new Match - i've just presumed some other Actor is sending a message.
(I'm typing on an ipad so the above code might not actually compile but hopefully you get the idea, i also left out an implementation of MatchActor, but it would just be an Actor that gets some values passed into its constructor)
Hope this helps!
There is an enormous amount of discussion on this topic, but everyone seems to miss an obvious answer. I'd like help vetting this "obvious" IOC container solution. The various conversations assume run-time selection of strategies and the use of an IOC container. I will continue with these assumptions.
I also want to add the assumption that it is not a single strategy that must be selected. Rather, I might need to retrieve an object-graph that has several strategies found throughout the nodes of the graph.
I will first quickly outline the two commonly proposed solutions, and then I will present the "obvious" alternative that I'd like to see an IOC container support. I will be using Unity as the example syntax, though my question is not specific to Unity.
Named Bindings
This approach requires that every new strategy has a binding manually added:
Container.RegisterType<IDataAccess, DefaultAccessor>();
Container.RegisterType<IDataAccess, AlphaAccessor>("Alpha");
Container.RegisterType<IDataAccess, BetaAccessor>("Beta");
...and then the correct strategy is explicitly requested:
var strategy = Container.Resolve<IDataAccess>("Alpha");
Pros: Simple, and supported by all IOC Containers
Cons:
Typically binds the caller to the IOC Container, and certainly requires the caller to know something about the strategy (such as the name "Alpha").
Every new strategy must be manually added to the list of bindings.
This approach is not suitable for handling multiple strategies in an object graph. In short, it does not meet requirements.
Abstract Factory
To illustrate this approach, assume the following classes:
public class DataAccessFactory{
public IDataAccess Create(string strategy){
return //insert appropriate creation logic here.
}
public IDataAccess Create(){
return //Choose strategy through ambient context, such as thread-local-storage.
}
}
public class Consumer
{
public Consumer(DataAccessFactory datafactory)
{
//variation #1. Not sufficient to meet requirements.
var myDataStrategy = datafactory.Create("Alpha");
//variation #2. This is sufficient for requirements.
var myDataStrategy = datafactory.Create();
}
}
The IOC Container then has the following binding:
Container.RegisterType<DataAccessFactory>();
Pros:
The IOC Container is hidden from consumers
The "ambient context" is closer to the desired result but...
Cons:
The constructors of each strategy might have different needs. But now the responsibility of constructor injection has been transferred to the abstract factory from the container. In other words, every time a new strategy is added it may be necessary to modify the corresponding abstract factory.
Heavy use of strategies means heavy amounts of creating abstract factories. It would be nice if the IOC container simply gave a little more help.
If this is a multi-threaded application and the "ambient context" is indeed provided by thread-local-storage, then by the time an object is using an injected abstract-factory to create the type it needs, it may be operating on a different thread which no longer has access to the necessary thread-local-storage value.
Type Switching / Dynamic Binding
This is the approach that I want to use instead of the above two approaches. It involves providing a delegate as part of the IOC container binding. Most all IOC Containers already have this ability, but this specific approach has an important subtle difference.
The syntax would be something like this:
Container.RegisterType(typeof(IDataAccess),
new InjectionStrategy((c) =>
{
//Access ambient context (perhaps thread-local-storage) to determine
//the type of the strategy...
Type selectedStrategy = ...;
return selectedStrategy;
})
);
Notice that the InjectionStrategy is not returning an instance of IDataAccess. Instead it is returning a type description that implements IDataAccess. The IOC Container would then perform the usual creation and "build up" of that type, which might include other strategies being selected.
This is in contrast to the standard type-to-delegate binding which, in the case of Unity, is coded like this:
Container.RegisterType(typeof(IDataAccess),
new InjectionFactory((c) =>
{
//Access ambient context (perhaps thread-local-storage) to determine
//the type of the strategy...
IDataAccess instanceOfSelectedStrategy = ...;
return instanceOfSelectedStrategy;
})
);
The above actually comes close to satisfying the overall need, but definitely falls short of the hypothetical Unity InjectionStrategy.
Focusing on the first sample (which used a hypothetical Unity InjectionStrategy):
Pros:
Hides the container
No need either to create endless abstract factories, or have consumers fiddle with them.
No need to manually adjust IOC container bindings whenever a new strategy is available.
Allows the container to retain lifetime management controls.
Supports a pure DI story, which means that a multi-threaded app can create the entire object-graph on a thread with the proper thread-local-storage settings.
Cons:
Because the Type returned by the strategy was not available when the initial IOC container bindings were created, it means there may be a tiny performance hit the first time that type is returned. In other words, the container must on-the-spot reflect the type to discover what constructors it has, so that it knows how to inject it. All subsequent occurrences of that type should be fast, because the container can cache the results it found from the first time. This is hardly a "con" worth mentioning, but I'm trying for full-disclosure.
???
Is there an existing IOC container that can behave this way? Anyone have a Unity custom injection class that achieves this effect?
As far as I can tell, this question is about run-time selection or mapping of one of several candidate Strategies.
There's no reason to rely on a DI Container to do this, as there are at least three ways to do this in a container-agnostic way:
Use a Metadata Role Hint
Use a Role Interface Role Hint
Use a Partial Type Name Role Hint
My personal preference is the Partial Type Name Role Hint.
I have achieved this requirement in many forms over the last couple of years. Firstly let's pull the main points I can see in your post
assume run-time selection of strategies and the use of an IOC container ... add the assumption that it is not a single strategy that must be selected. Rather, I might need to retrieve an object-graph that has several strategies ... [must not] binds the caller to the IOC Container ... Every new strategy must [not need to] be manually added to the list of bindings ... It would be nice if the IOC container simply gave a little more help.
I have used Simple Injector as my container of choice for some time now and one of the drivers for this decision is that it has extensive support for generics. It is through this feature that we will implement your requirements.
I'm a firm believer that the code should speak for itself so I'll jump right in ...
I have defined an extra class ContainerResolvedClass<T> to demonstrate that Simple Injector finds the right implementation(s) and successfully injects them into a constructor. That is the only reason for the class ContainerResolvedClass<T>. (This class exposes the handlers that are injected into it for test purposes via result.Handlers.)
This first test requires that we get one implementation back for the fictional class Type1:
[Test]
public void CompositeHandlerForType1_Resolves_WithAlphaHandler()
{
var container = this.ContainerFactory();
var result = container.GetInstance<ContainerResolvedClass<Type1>>();
var handlers = result.Handlers.Select(x => x.GetType());
Assert.That(handlers.Count(), Is.EqualTo(1));
Assert.That(handlers.Contains(typeof(AlphaHandler<Type1>)), Is.True);
}
This second test requires that we get one implementation back for the fictional class Type2:
[Test]
public void CompositeHandlerForType2_Resolves_WithAlphaHandler()
{
var container = this.ContainerFactory();
var result = container.GetInstance<ContainerResolvedClass<Type2>>();
var handlers = result.Handlers.Select(x => x.GetType());
Assert.That(handlers.Count(), Is.EqualTo(1));
Assert.That(handlers.Contains(typeof(BetaHandler<Type2>)), Is.True);
}
This third test requires that we get two implementations back for the fictional class Type3:
[Test]
public void CompositeHandlerForType3_Resolves_WithAlphaAndBetaHandlers()
{
var container = this.ContainerFactory();
var result = container.GetInstance<ContainerResolvedClass<Type3>>();
var handlers = result.Handlers.Select(x => x.GetType());
Assert.That(handlers.Count(), Is.EqualTo(2));
Assert.That(handlers.Contains(typeof(AlphaHandler<Type3>)), Is.True);
Assert.That(handlers.Contains(typeof(BetaHandler<Type3>)), Is.True);
}
These tests seems to meet your requirements and best of all no containers are harmed in the solution.
The trick is to use a combination of parameter objects and marker interfaces. The parameter objects contain the data for the behaviour (i.e. the IHandler's) and the marker interfaces govern which behaviours act on which parameter objects.
Here are the marker interfaces and parameter objects - you'll note that Type3 is marked with both marker interfaces:
private interface IAlpha { }
private interface IBeta { }
private class Type1 : IAlpha { }
private class Type2 : IBeta { }
private class Type3 : IAlpha, IBeta { }
Here are the behaviours (IHandler<T>'s):
private interface IHandler<T> { }
private class AlphaHandler<TAlpha> : IHandler<TAlpha> where TAlpha : IAlpha { }
private class BetaHandler<TBeta> : IHandler<TBeta> where TBeta : IBeta { }
This is the single method that will find all implementations of an open generic:
public IEnumerable<Type> GetLoadedOpenGenericImplementations(Type type)
{
var types =
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from t in assembly.GetTypes()
where !t.IsAbstract
from i in t.GetInterfaces()
where i.IsGenericType
where i.GetGenericTypeDefinition() == type
select t;
return types;
}
And this is the code that configures the container for our tests:
private Container ContainerFactory()
{
var container = new Container();
var types = this.GetLoadedOpenGenericImplementations(typeof(IHandler<>));
container.RegisterAllOpenGeneric(typeof(IHandler<>), types);
container.RegisterOpenGeneric(
typeof(ContainerResolvedClass<>),
typeof(ContainerResolvedClass<>));
return container;
}
And finally, the test class ContainerResolvedClass<>
private class ContainerResolvedClass<T>
{
public readonly IEnumerable<IHandler<T>> Handlers;
public ContainerResolvedClass(IEnumerable<IHandler<T>> handlers)
{
this.Handlers = handlers;
}
}
I realise this post is a quite long, but I hope it clearly demonstrates a possible solution to your problem ...
This is a late response but maybe it will help others.
I have a pretty simple approach. I simply create a StrategyResolver to not be directly depending on Unity.
public class StrategyResolver : IStrategyResolver
{
private IUnityContainer container;
public StrategyResolver(IUnityContainer unityContainer)
{
this.container = unityContainer;
}
public T Resolve<T>(string namedStrategy)
{
return this.container.Resolve<T>(namedStrategy);
}
}
Usage:
public class SomeClass: ISomeInterface
{
private IStrategyResolver strategyResolver;
public SomeClass(IStrategyResolver stratResolver)
{
this.strategyResolver = stratResolver;
}
public void Process(SomeDto dto)
{
IActionHandler actionHanlder = this.strategyResolver.Resolve<IActionHandler>(dto.SomeProperty);
actionHanlder.Handle(dto);
}
}
Registration:
container.RegisterType<IActionHandler, ActionOne>("One");
container.RegisterType<IActionHandler, ActionTwo>("Two");
container.RegisterType<IStrategyResolver, StrategyResolver>();
container.RegisterType<ISomeInterface, SomeClass>();
Now, the nice thing about this is that I will never have to touch the StrategyResolver ever again when adding new strategies in the future.
It's very simple. Very clean and I kept the dependency on Unity to a strict minimum. The only time I would have touch the StrategyResolver is if I decide to change container technology which is very unlikely to happen.
Hope this helps!
I generally use a combination of your Abstract Factory and Named Bindings options. After trying many different approaches, I find this approach to be a decent balance.
What I do is create a factory that essentially wraps the instance of the container. See the section in Mark's article called Container-based Factory. As he suggests, I make this factory part of the composition root.
To make my code a little cleaner and less "magic string" based, I use an enum to denote the different possible strategies, and use the .ToString() method to register and resolve.
From your Cons of these approaches:
Typically binds the caller to the IOC Container
In this approach, the container is referenced in the factory, which is part of the Composition Root, so this is no longer an issue (in my opinion).
. . . and certainly requires the caller to know something about the strategy (such as the
name "Alpha").
Every new strategy must be manually added to the list
of bindings. This approach is not suitable for handling multiple
strategies in an object graph. In short, it does not meet
requirements.
At some point, code needs to be written to acknowledge the mapping between the structure that provides the implementation (container, provider, factory, etc.) and the code that requires it. I don't think you can get around this unless you want to use something that is purely convention-based.
The constructors of each strategy might have different needs. But now the responsibility of constructor injection has been transferred to the abstract factory from the container. In other words, every time a new strategy is added it may be necessary to modify the corresponding abstract factory.
This approach solves this concern completely.
Heavy use of strategies means heavy amounts of creating abstract factories.[...]
Yes, you will need one abstract factory for each set of strategies.
If this is a multi-threaded application and the "ambient context" is indeed provided by thread-local-storage, then by the time an object is using an injected abstract-factory to create the type it needs, it may be operating on a different thread which no longer has access to the necessary thread-local-storage value.
This will no longer be an issue since TLC will not be used.
I don't feel that there is a perfect solution, but this approach has worked well for me.
I am currently weighing up the advantages and disadvantages between DI and SL. However, I have found myself in the following catch 22 which implies that I should just use SL for everything, and only inject an IoC container into each class.
DI Catch 22:
Some dependencies, like Log4Net, simply do not suit DI. I call these meta-dependencies and feel they should be opaque to calling code. My justification being that if a simple class 'D' was originally implemented without logging, and then grows to require logging, then dependent classes 'A', 'B', and 'C' must now somehow obtain this dependency and pass it down from 'A' to 'D' (assuming 'A' composes 'B', 'B' composes 'C', and so on). We have now made significant code changes just because we require logging in one class.
We therefore require an opaque mechanism for obtaining meta-dependencies. Two come to mind: Singleton and SL. The former has known limitations, primarily with regards to rigid scoping capabilities: at best a Singleton will use an Abstract Factory which is stored at application scope (ie. in a static variable). This allows some flexibility, but is not perfect.
A better solution would be to inject an IoC container into such classes, and then use SL from within that class to resolve these meta-dependencies from the container.
Hence catch 22: because the class is now being injected with an IoC container, then why not use it to resolve all other dependencies too?
I would greatly appreciate your thoughts :)
Because the class is now being injected with an IoC container, then why not use it to resolve all other dependencies too?
Using the service locator pattern completely defeats one of the main points of dependency injection. The point of dependency injection is to make dependencies explicit. Once you hide those dependencies by not making them explicit parameters in a constructor, you're no longer doing full-fledged dependency injection.
These are all constructors for a class named Foo (set to the theme of the Johnny Cash song):
Wrong:
public Foo() {
this.bar = new Bar();
}
Wrong:
public Foo() {
this.bar = ServiceLocator.Resolve<Bar>();
}
Wrong:
public Foo(ServiceLocator locator) {
this.bar = locator.Resolve<Bar>();
}
Right:
public Foo(Bar bar) {
this.bar = bar;
}
Only the latter makes the dependency on Bar explicit.
As for logging, there's a right way to do it without it permeating into your domain code (it shouldn't but if it does then you use dependency injection period). Amazingly, IoC containers can help with this issue. Start here.
Service Locator is an anti-pattern, for reasons excellently described at http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx. In terms of logging, you could either treat that as a dependency just like any other, and inject an abstraction via constructor or property injection.
The only difference with log4net, is that it requires the type of the caller that uses the service. Using Ninject (or some other container) How can I find out the type that is requesting the service? describes how you can solve this (it uses Ninject, but is applicable to any IoC container).
Alternatively, you could think of logging as a cross cutting concern, which isn't appropriate to mix with your business logic code, in which case you can use interception which is provided by many IoC containers. http://msdn.microsoft.com/en-us/library/ff647107.aspx describes using interception with Unity.
My opinion is that it depends. Sometimes one is better and sometimes another. But I'd say that generaly I prefer DI. There are few reasons for that.
When dependency is injected somehow into component it can be treated as part of its interface. Thus its easier for component's user to supply this dependecies, cause they are visible. In case of injected SL or Static SL that dependencies are hidden and usage of component is a bit harder.
Injected dependecies are better for unit testing cause you can simply mock them. In case of SL you have to setup Locator + mock dependencies again. So it is more work.
Sometimes logging can be implemented using AOP, so that it doesn't mix with business logic.
Otherwise, options are :
use an optional dependency (such as setter property), and for unit test you don't inject any logger. IOC container will takes care of setting it automatically for you if you run in production.
When you have a dependency that almost every object of your app is using ("logger" object being the most commmon example), it's one of the few cases where the singleton anti-pattern becomes a good practice. Some people call these "good singletons" an Ambient Context:
http://aabs.wordpress.com/2007/12/31/the-ambient-context-design-pattern-in-net/
Of course this context has to be configurable, so that you can use stub/mock for unit testing.
Another suggested use of AmbientContext, is to put the current Date/Time provider there , so that you can stub it during unit test, and accelerates time if you want.
This is regarding the 'Service Locator is an Anti-Pattern' by Mark Seeman.
I might be wrong here. But I just thought I should share my thoughts too.
public class OrderProcessor : IOrderProcessor
{
public void Process(Order order)
{
var validator = Locator.Resolve<IOrderValidator>();
if (validator.Validate(order))
{
var shipper = Locator.Resolve<IOrderShipper>();
shipper.Ship(order);
}
}
}
The Process() method for OrderProcessor does not actually follow the 'Inversion of Control' principle. It also breaks the Single Responsibility principle at the method level. Why should a method be concerned with instantiating the
objects(via new or any S.L. class) it needs to accomplish anything.
Instead of having the Process() method create the objects the constructor can actually have the parameters for the respective objects(read dependencies) as shown below. Then HOW can a Service Locator be any different from a IOC
container. AND it will aid in Unit Testing as well.
public class OrderProcessor : IOrderProcessor
{
public OrderProcessor(IOrderValidator validator, IOrderShipper shipper)
{
this.validator = validator;
this.shipper = shipper;
}
public void Process(Order order)
{
if (this.validator.Validate(order))
{
shipper.Ship(order);
}
}
}
//Caller
public static void main() //this can be a unit test code too.
{
var validator = Locator.Resolve<IOrderValidator>(); // similar to a IOC container
var shipper = Locator.Resolve<IOrderShipper>();
var orderProcessor = new OrderProcessor(validator, shipper);
orderProcessor.Process(order);
}
I have used the Google Guice DI framework in Java, and discovered that it does much more than make testing easier. For example, I needed a separate log per application (not class), with the further requirement that all my common library code use the logger in the current call context. Injecting the logger made this possible. Admittedly, all the library code needed to be changed: the logger was injected in the constructors. At first, I resisted this approach because of all the coding changes required; eventually I realized that the changes had many benefits:
The code became simpler
The code became much more robust
The dependencies of a class became obvious
If there were many dependencies, it was a clear indication that a class needed refactoring
Static singletons were eliminated
The need for session or context objects disappeared
Multi-threading became much easier, because the DI container could be built to contain just one thread, thus eliminating inadvertent cross-contamination
Needless to say, I am now a big fan of DI, and use it for all but the most trivial applications.
We've landed on a compromise: use DI but bundle top-level dependencies into an object avoiding refactoring hell should those dependencies change.
In the example below, we can add to 'ServiceDependencies' without having to refactor all derived dependencies.
Example:
public ServiceDependencies{
public ILogger Logger{get; private set;}
public ServiceDependencies(ILogger logger){
this.Logger = logger;
}
}
public abstract class BaseService{
public ILogger Logger{get; private set;}
public BaseService(ServiceDependencies dependencies){
this.Logger = dependencies.Logger; //don't expose 'dependencies'
}
}
public class DerivedService(ServiceDependencies dependencies,
ISomeOtherDependencyOnlyUsedByThisService additionalDependency)
: base(dependencies){
//set local dependencies here.
}
I know that people are really saying DI is the only good IOC pattern but I don't get this. I will try to sell SL a bit. I will use the new MVC Core framework to show you what I mean. First DI engines are really complex. What people really mean when they say DI, is use some framework like Unity, Ninject, Autofac... that do all the heavy lifting for you, where SL can be as simple as making a factory class. For a small fast project this is an easy way to do IOC without learning a whole framework for proper DI, they might not be that difficult to learn but still.
Now to the problem that DI can become. I will use a quote from MVC Core docs.
"ASP.NET Core is designed from the ground up to support and leverage dependency injection." Most people say that about DI "99% of your code base should have no knowledge of your IoC container." So why would they need to design from ground up if only 1% of code should be aware of it, didn't old MVC support DI? Well this is the big problem of DI it depends on DI. Making everything work "AS IT SHOULD BE DONE" takes a lot of work. If you look at the new Action Injection is this not depending on DI if you use [FromServices] attribute. Now DI people will say NO you are suppose to go with Factories not this stuff, but as you can see not even people making MVC did it right. The problem of DI is visible in Filters as well look at what you need to do to get DI in a filter
public class SampleActionFilterAttribute : TypeFilterAttribute
{
public SampleActionFilterAttribute():base(typeof(SampleActionFilterImpl))
{
}
private class SampleActionFilterImpl : IActionFilter
{
private readonly ILogger _logger;
public SampleActionFilterImpl(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<SampleActionFilterAttribute>();
}
public void OnActionExecuting(ActionExecutingContext context)
{
_logger.LogInformation("Business action starting...");
// perform some business logic work
}
public void OnActionExecuted(ActionExecutedContext context)
{
// perform some business logic work
_logger.LogInformation("Business action completed.");
}
}
}
Where if you used SL you could have done this with var _logger = Locator.Get();. And then we come to the Views. With all there good will regarding DI they had to use SL for the views. the new syntax #inject StatisticsService StatsService is the same as var StatsService = Locator.Get<StatisticsService>();.
The most advertised part of DI is unit testing. But what people and up doing is just testing there mock services with no purpose or having to wire up there DI engine to do real tests. And I know that you can do anything badly but people end up making a SL locator even if they don't know what it is. Where not a lot of people make DI without ever reading on it first.
My biggest problem with DI is that the user of the class must be aware of the inner workings of the class in other to use it.
SL can be used in a good way and has some advantages most of all its simplicity.
I know this question is a little old, I just thought I would give my input.
In reality, 9 times out of 10 you really don't need SL and should rely on DI. However, there are some cases where you should use SL. One area that I find myself using SL (or a variation, thereof) is in game development.
Another advantage of SL (in my opinion) is the ability to pass around internal classes.
Below is an example:
internal sealed class SomeClass : ISomeClass
{
internal SomeClass()
{
// Add the service to the locator
ServiceLocator.Instance.AddService<ISomeClass>(this);
}
// Maybe remove of service within finalizer or dispose method if needed.
internal void SomeMethod()
{
Console.WriteLine("The user of my library doesn't know I'm doing this, let's keep it a secret");
}
}
public sealed class SomeOtherClass
{
private ISomeClass someClass;
public SomeOtherClass()
{
// Get the service and call a method
someClass = ServiceLocator.Instance.GetService<ISomeClass>();
someClass.SomeMethod();
}
}
As you can see, the user of the library has no idea this method was called, because we didn't DI, not that we'd be able to anyways.
If the example only takes log4net as dependency, then you only need to do this:
ILog log = LogManager.GetLogger(typeof(Foo));
There is no point to inject the dependency as log4net provides granular logging by taking the type (or a string) as parameter.
Also, DI is not correlated with SL. IMHO the purpose of ServiceLocator is for resolve optional dependencies.
Eg: If the SL provides an ILog interface, i will write logging daa.
For DI, do you need to have a hard reference to the injected type assembly? I don’t see anyone talking about that. For SL, I can tell my resolver where to load my type dynamically when it needed from a config.json or similar. Also, if your assembly contains several thousand types and their inheritance, do you need thousands cascading call to the service collection provider to register them? That’s where I do see much talk about. Most are talking about the benefit of DI and what it is in general, when it comes to how to implement it in .net, they presented with an extension method for adding reference to a hard linked types assembly. That’s not very decoupling to me.
Summary: I want to know the best design for creating cross-platform (eg. desktop, web, and Silverlight) classes in C#, with no duplication of code, with the pros and cons of each design.
I'm often writing new, useful classes for one application domain; there's no reason why they won't work across domains. How can I structure my code to make it ideally cross-platform?
For example, let's say I wanted to make a generic "MyTimer" class with an interval and on-tick event. In desktop, this would use the built-in .NET timer. In Silverlight, I would use a DispatchTimer.
Design #1 might be "create a class and use pre-processor directives for conditional compilation," eg. "#IF SILVERILGHT ...". However, this leads to code that is less understandable, readable, and maintainable.
Design #2 might be "create subclasses called DesktopTimer and SilverlightTimer and consume those from MyTimer." How would that work?
While this is a trivial case, I may have more complicated classes that, for example, consume platform-specific classes (IsolatedStorage, DispatchTimer, etc.) but aren't directly replacing them.
What other designs/paradigms can I use?
I would suggest writing Interfaces that you would simply implement for your platform specific code. Then, the interfaces assure that your code will respect the contracts given by your interface, otherwise there will be a code break (if one member is not implemented).
Besides, within this library where resides your specific timer classes, to stick to your example, I would create a class for each platform, thus using the DispatchTimer for Silverlight, and the built-in .NET timer for the desktop version.
In the end, you would end up using only one interface that only its implementers know how to deal with the contract specifically to your underlying platform.
EDIT #1
Conditonal design is not an option for a good design. Here is a tool that will help you deal with the Dependancy Injection, that is called Unity Application Block, and is used to deal with such scenario like yours.
You only use an XML configuration that is very versatile to "tell" what has to be instantiated when this or that interface is needed. Then, the UnityContainer consults with the configuration you have made, and instantiate the right class for you. This assures good design approach and architecture.
EDIT #2
I'm not very familiar with Dependency Injection, and not at all familiar with Unity Application Block. Can you point to some resources or explain these a bit further?
Microsoft Enterprise Library 5.0 - April 2010;
Microsoft Unity 2.0 – April 2010;
Microsoft Unity 2.0 Documentation for Visual Studio 2008;
Are there good tutorial/walkthroughs for unity that don't use configuration files? (SO question on the topic that should provide valuable hints to start with Unity);
Specifying Types in the Configuration File;
Walkthrough: The Unity StopLight QuickStart;
Walkthrough: The Unity Event Broker Extension QuickStart.
I think these resources shall guide you through your learnings. If you need further assistance, please let me know! =)
EDIT #3
But anyway, the StopLight quickstart [...] seems to imply that the dependency mapping of interface to concrete class is done in code (which won't work for me).
In fact, you can do both code and XML dependency mapping, the choice is yours! =)
Here are some example that you should perhaps inspire from to make the StopLight quickstart use the XML configuration instead of the coded mapping.
Testing Your Unity XML Configuration;
Using Design-Time Configuration;
Source Schema for the Unity Application Block.
If this doesn't help you get through, let me know. I shall then provide a simple example using XML dependency mapping. =)
1) Interfaces with platform-specific class in their own assemblies: ITimer in a shared assembly, and a "WebAssembly" containing WebTimer, for example. Then the "WebAssembly.dll", or "DesktopAssembly.dll" are on-demand loaded. This turns it into more of a deployment/configuration issue, and everything compiles. Dependency Injection or MEF become a great help here.
2) Interfaces (again), but with conditional compilation. This makes it less of a deployment issue, and more of a compilation problem. WebTimer would have #ifdef WEB_PLATFORM around it, and so on.
Personally, I'd lean to #1 - but in a complicated application, most likely you'll end up having to use both because of slight changes in the available parts of the .net framework between silverlight and everything else. You may even want different behavior in core parts of your app just for the performance issues.
I think interfaces are a good choice here (defining what a timer will do without actually implementing it)
public interface ITimer
{
void CreateTimer(int _interval, TimerDelegate _delegate);
void StopTimer();
// etc...
} // eo interface ITimer
From this, you derive your concrete timers:
public class DesktopTimer : ITimer
{
} // eo DesktopTimer
public class SilverlightTimer : ITimer
{
} // eo class SilverlightTimer
public class WebTimer : Timer
{
} // eo class WebTimer
Then comes the fun part. How do we create the right timer? Here you could implement some kind of platform-factory that returned the right timer depending on what platform it is running on. Here is a quick and dirty idea (I would make it more dynamic than this, and perhaps implement one factory for multiple kinds of classes, but this is an example)
public enum Platform
{
Desktop,
Web,
Silverlight
} // eo enum Platform
public class TimerFactory
{
private class ObjectInfo
{
private string m_Assembly;
private string m_Type;
// ctor
public ObjectInfo(string _assembly, string _type)
{
m_Assembly = _assembly;
m_Type = _type;
} // eo ctor
public ITimer Create() {return(AppDomain.CurrentDomain.CreateInstanceAndUnwrap(m_Assembly, m_Type));}
} // eo class ObjectInfo
Dictionary<Platform, ObjectInfo> m_Types = new Dictionary<PlatForm, ObjectInfo>();
public TimerFactory()
{
m_Types[Platform.Desktop] = new ObjectInfo("Desktop", "MyNamespace.DesktopTimer");
m_Types[Platform.Silverlight] = new ObjectInfo("Silverlight", "MyNameSpace.SilverlightTimer");
// ...
} // eo ctor
public ITimer Create()
{
// based on platform, create appropriate ObjectInfo
} // eo Create
} // eo class TimerFactory
As I mentioned above, I would not have a factory for every time of object, but make a generic platform-factory that could handle timers, containers and whatever else you want. This is just an example.
The Model-View-Presenter pattern is a really good approach if you want to separate all of your user interface logic from the actual GUI framework you are using. Read Michael Feather's article "The Humble Dialog Box" to get an excellent explanation of how it works:
http://www.objectmentor.com/resources/articles/TheHumbleDialogBox.pdf
The original article was made for C++, if you want a C# example, look here:
http://codebetter.com/blogs/jeremy.miller/articles/129546.aspx
The Pros are:
you will make your GUI logic resusable
your GUI logic becomes applicable for unit testing
The Cons:
if your program does not need more than one GUI framework, this approach produces more lines-of-code, and you have to deal with more complexity, since you have to decide all through your coding which parts of your code belong into the view and which into the presenter
Go with all OOD you know. I'd suggest creating platform-agnostic (Windows, Mono/destkop, web) domain model. Use abstract classes to model platform-dependant stuff (like the Timer). Use Dependency Injection and/or Factory patterns to use specific implementations.
EDIT: at some point you have to specify what concrete classes to use, but using the abovementioned patterns can bring all that code into one place without using conditional compilation.
EDIT: an example of DI/Factory. Of course you can use on of existing frameworks, which will give you more power and expressivenes. For the simple example it seems like an overkill, but the more complicated the code, the bigger the gain of using the patterns.
// Common.dll
public interface IPlatformInfo
{
string PlatformName { get; }
}
public interface PlatformFactory
{
IPlatformInfo CreatePlatformInfo();
// other...
}
public class WelcomeMessage
{
private IPlatformInfo platformInfo;
public WelcomeMessage(IPlatformInfo platformInfo)
{
this.platformInfo = platformInfo;
}
public string GetMessage()
{
return "Welcome at " + platformInfo.PlatformName + "!";
}
}
// WindowsApp.exe
public class WindowsPlatformInfo : IPlatformInfo
{
public string PlatformName
{
get { return "Windows"; }
}
}
public class WindowsPlatformFactory : PlatformFactory
{
public IPlatformInfo CreatePlatformInfo()
{
return new WindowsPlatformInfo();
}
}
public class WindowsProgram
{
public static void Main(string[] args)
{
var factory = new WindowsPlatformFactory();
var message = new WelcomeMessage(factory.CreatePlatformInfo());
Console.WriteLine(message.GetMessage());
}
}
// MonoApp.exe
public class MonoPlatformInfo : IPlatformInfo
{
public string PlatformName
{
get { return "Mono"; }
}
}
public class MonoPlatformFactory : PlatformFactory
{
public IPlatformInfo CreatePlatformInfo()
{
return new MonoPlatformInfo();
}
}
public class MonoProgram
{
public static void Main(string[] args)
{
var factory = new MonoPlatformFactory();
var message = new WelcomeMessage(factory.CreatePlatformInfo());
Console.WriteLine(message.GetMessage());
}
}
As others have sugested, interfaces are the way to go here. I would alter the interface from sugestion Moo-Juice suggestion slightly...
`
//Why is this block not formated like code???
public interface ITimer{
void StopTimer(); // etc...
void StartTimer(); // etc...
TimeSpan Duration {get;} // eo interface ITimer
}`
Now you would need to get the ITimer into your class that is using it. The most timple way to do this is called dependency injection. The most common approach to achieve this is called constructor injection.
So when creating a class that needs a timer you pass a timer into the class when creating one.
Basically you do:
var foo = new Foo(new WebTimer());
Since that will get complicated quite fast, you can utilize some helpers. This pattern is called inversion of control. There are some frameworks that will help you, like the ninject or castle windsor.
Both are inversion of control (IOC) containers. (Thats the secret sauce)
Basically you "register" your timer in the IOC, and also register your "Foo". When you need a "Foo", you ask your IOC Container to create one. The container looks at the constructor, finds that it needs a ITimer. It will then create an ITimer for you, and pass it into the constructor, and finally hand you the complete class.
Inside you class you dont need to have any knowledge about the ITimer, or how to create it, since all that was moved to the outside.
For different Applications you now only need to register the correct components, and you are done...
P.s.: Be carefull and dont confuse the IOC Container with a service locator...
Links:
http://ninject.org/download
http://www.castleproject.org/container/index.html
http://www.pnpguidance.net/Category/Unity.aspx
Why not have configuration section which will tell your library about the platform of the host application. This you have to set only once in your application to the host config file (web.config or app.config), and rest you can use using Factory method as suggested by Moo-Juice. You can use platform detail over entire functionality of the library.