Wondering if someone can throw some guidance my way. My standard application setup has always been nTier application (Presentation, Business, Data and usually a Common). I've avoided setting up and IoC container (used them in other people's apps for ages, just not set them up) for as long as I can but finally having to take the plunge.
My understanding of IoC allows dependency injection which in turn makes unit testing possible (well a lot easier) so in my head I'd want to at least perform unit tests on the Business Layer....but every example of setting up IoC like StructureMap makes the IoC on the Presentation layer. So...what I'm asking is what is the 'best practice' for nTier App with an IoC.
Thanks.
The primary benefit of DI is not unit testing (although that is certainly a benefit). The primary benefit is loose-coupling. An application that is "testable" is not necessarily loosely-coupled.
However, loose-coupling brings a lot more to the table than just testability.
Loose Coupling Benefits
Late Binding (services can be swapped with other services, often without changing existing code)
Extensibility (code can be extended, often without changing existing code)
Parallel development (abstract contracts are defined that multiple developers can adhere to)
Maintainability (classes with clearly defined responsibilities are easier to maintain)
Testability (classes are easier to test).
IMHO, when combining DI with software patterns, extensibility is definitely the main benefit. Consider the following types:
public interface IWriter
{
void WriteSomething();
}
public interface ISomeService
{
void Write();
}
You could extend a service by using a Decorator Pattern:
public class NullWriter : IWriter
{
public void WriteSomething()
{
// Do nothing - this is a "null object pattern".
}
}
public class HelloWriter : IWriter
{
public readonly IWriter innerWriter;
public HelloWriter(IWriter innerWriter)
{
if (innerWriter == null)
throw new ArgumentNullException("innerWriter");
this.innerWriter = innerWriter;
}
public void WriteSomething()
{
this.innerWriter.WriteSomething();
Console.WriteLine("Hello.");
}
}
public class GoodbyeWriter : IWriter
{
public readonly IWriter innerWriter;
public GoodbyeWriter(IWriter innerWriter)
{
if (innerWriter == null)
throw new ArgumentNullException("innerWriter");
this.innerWriter = innerWriter;
}
public void WriteSomething()
{
this.innerWriter.WriteSomething();
Console.WriteLine("Goodbye.");
}
}
public class SomeService : ISomeService
{
private readonly IWriter writer;
public SomeService(IWriter writer)
{
if (writer == null)
throw new ArgumentNullException("writer");
}
public void Write()
{
this.writer.WriteSomething();
}
}
And the above would be wired up like:
// Composition Root
var nullWriter = new NullWriter();
var goodbyeWriter = new GoodbyeWriter(nullWriter);
var helloWriter = new HelloWriter(goodbyeWriter);
var service = new SomeService(helloWriter);
// End Composition Root
// Execute
service.Write();
//Writes:
//Hello.
//Goodbye.
Now, that the scenario is set up, you can extend what SomeService does without altering any of the existing types. The only part of the application that needs to change is the composition root.
public class HowAreYouWriter : IWriter
{
public readonly IWriter innerWriter;
public HowAreYouWriter(IWriter innerWriter)
{
if (innerWriter == null)
throw new ArgumentNullException("innerWriter");
this.innerWriter = innerWriter;
}
public void WriteSomething()
{
this.innerWriter.WriteSomething();
Console.WriteLine("How are you?");
}
}
// Composition Root
var nullWriter = new NullWriter();
var goodbyeWriter = new GoodbyeWriter(nullWriter);
var howAreYouWriter = new HowAreYouWriter(goodbyeWriter);
var helloWriter = new HelloWriter(howAreYouWriter);
var service = new SomeService(helloWriter);
// End Composition Root
// Execute
service.Write();
//Writes:
//Hello.
//How are you?
//Goodbye.
Convention over Configuration
One additional (often overlooked) benefit of DI is Convention over Configuration. When combining constructor injection with a DI container, many of them provide the ability to map ISomeService to SomeService automatically. Some containers (like StructureMap) also have the ability to build your own conventions.
The benefit isn't obvious because it really doesn't start to pay off until you are registering dozens of types using the convention. However, you can considerably reduce the amount of code it takes to compose your application if you use them.
N-Tier App
For a single application, there is normally a single composition root as close to the entry point of the application as possible. In MVC, that would be within the HttpApplication.Start method.
However, this may vary depending on whether you consider the layers of the application design to be DI Friendly Libraries or DI Friendly Frameworks and whether you consider a piece of the application as being a "plug in" that you add to after it is built (basically, making a composition root that can load dynamic dependencies).
There are essentially 3 approaches that are commonly followed to solve this issue:
Make all of the types public and compose them in the same project that contains your presentation layer.
Put a composition root into each layer and make the public API of each layer use DI internally. Then compose the public API of the layer using the main project. In general, you will also need to make a public Compose method on each layer that is called from the main Compose method.
Make a separate composition root project to compose all of the pieces together.
I have even seen some people recommend to put all of your "layers" into a single project, and if you don't intend to use these pieces individually, there isn't that much of a downside. The NuGet Gallery is one such project that is built this way.
IMHO, making everything public and putting the composition root in the main application is usually the best option for a single multi-layer application whose parts aren't intended to be used with another application.
Final Word
If you are serious about learning DI, pick up the book Dependency Injection in .NET by Mark Seemann. You might not think of DI as being a big enough area of development to study on its own, but this book really does provide many benefits that extend beyond just DI, such as SOLID principles.
Related
With DDD and some of the other abstraction principles out there, when the need arises to instantiate unstable instances (negating stable C# instantiation and primitives), the logic for Factory pattern makes sense (at times) when needing to define business logic while instantiating (security benefits, performance with possibly not needing memory allocations for new, etc.), however, what if the instance does not require any instantiation logic, but itself as well as other related models are used in multiple places in the same class (Example being the very simplified code created below ... changing public to least privileges where applicable, etc.)
Are there benefits of abstracting out the instantiation into a factory pattern as opposed to inline instantiation (be it dependency inversion or other)? ... most searches I've found touch on the pros and cons of the factory pattern, the alternatives, static vs DI (Bloch's Effective Java), etc.
public interface IUserTypeFactory
{
User CreateUser();
Admin CreateAdmin();
Reporter CreateReporter();
}
public class UserTypeFactory : IUserTypeFactory
{
public User CreateUser() => new User();
public Admin CreateAdmin() => new Admin();
public Reporter CreateReporter() => new Reporter();
}
public class UserService
{
private readonly IUserTypeFactory _userTypeFactory;
public UserService(IUserTypeFactory userTypeFactory) => _userTypeFactory = userTypeFactory;
public void DoSomething()
{
var user = _userTypeFactory.CreateUser();
// .. business logic
}
// More Methods requiring instantiation
}
Two benefits, one somewhat abstract and one practical.
Object instantiation is a separate responsibility. Under SRP, your business logic code should not be doing it. The responsibility of object creation belongs to the composition root and to factories.
If your code uses new there is more or less no way to substitute another class for unit testing. If your code uses an IXXXFactory of some kind, your unit test code can supply its own factory which would return mock or stub objects, allowing you to isolate the class under test. This makes unit testing much easier.
I am using autofac in my UWP application.
I am using the facade pattern for my backend and it is represented by an IFacade interface.
public interface IFacade
{
/* forwards view-models' calls to different parts of the backend */
}
The view-models of my UWP application are using an implementation of IFacade whose concrete implementation is resolved through autofac in the UWP's App instance.
public class App : Application
{
...
private IFacade InitializeDependencies()
{
var containerBuilder = new ContainerBuilder();
// Registers all the platform-specific implementations of services.
containerBuilder.RegisterType<LoggingService>().As<ILoggingService>().SingleInstance();
containerBuilder.RegisterType<SQLitePlatformService>().As<ISQLitePlatformService>().SingleInstance();
containerBuilder.RegisterType<DiskStorageService>().As<IDiskStorageService>().SingleInstance();
containerBuilder.RegisterType<IdentityProviderFactoryService>().As<IIdentityProviderFactoryService>().SingleInstance();
containerBuilder.RegisterType<DefaultVaultService>().As<IVaultService>().SingleInstance();
containerBuilder.RegisterType<LocationService>().As<ILocationService>().SingleInstance();
containerBuilder.RegisterType<NavigationService>().As<INavigationService>().SingleInstance();
// Registers all the dependencies of the Backend project.
var backendDependencies = new Dependencies();
backendDependencies.Setup(containerBuilder);
// Resolves the IFacade.
var container = containerBuilder.Build();
var lifetimeScope = container.BeginLifetimeScope();
return backendDependencies.ResolveFacade(lifetimeScope);
}
I have a lot of services in my backend and my implementation of IFacade ends up with that horrific constructor referencing a lot of services' interfaces, something would make Uncle Bob cringe.
internal sealed Facade : IFacade
{
public Facade(ISessionService sessionService, IEntitiesRepository entitiesRepository, ISynchronizationService synchronizationService, IVaultService vaultService, IIdentityProviderFactoryService identityProviderFactoryService, IDemoTapeService demoTapeService, IDiskStorageService diskStorageService)
{
/* Saves the references as read-only fields. */
}
}
Question
Contrary to the ServiceLocator, using DI forces us to make all the dependencies that are needed visible. I am not sure if I am using the Dependency Injection properly.
What can I do so that my constructor of my Facade class does not have that many parameters?
Solutions tried
Properties
I could change the Facade class and inject the services through public properties. I am not fond of lots of public get / set as my IFacade contract would now indicate that those properties could be changed after the Facade implementation is created, which is not something I want to support (and debug).
Aggregate interfaces
Another option would be to aggregate interfaces together (something that I call the SomethingContext classes) but then it is harder to understand what these groups of interfaces would mean.
Inject a ServiceLocator that is not static in the Facade constructor
The last solution that seems more acceptable (well... acceptable to me) would be to use DI to inject a non-static ServiceLocator. It is kind of solution 2). However, I know the ServiceLocator is something that is frowned upon.
So one another approach is to create some smaller Facade Services and then inject those services to the main facade.
For example you can create such smaller facade for INavigationService and ILocationService:
public class GeographyService : IGeographyService
{
public GeographyService(
INavigationService navigationService,
ILocationService locationService)
{
}
}
The same is true for ISQLitePlatformService and DiskStorageService:
public class StorageService : IStorageService
{
public StorageService(
ISQLitePlatformService databaseService,
DiskStorageService diskStorageService)
{
}
}
That's of course only an example of an idea.
Such an approach is generally considered better than aggregate services with all the dependencies aggregated (http://autofaccn.readthedocs.io/en/latest/advanced/aggregate-services.html) or ServiceLocator (anti-)pattern. You can also read some thoughts about it here: http://blog.ploeh.dk/2010/02/02/RefactoringtoAggregateServices/
I have implemented a solution that has some core reusable classes that are easily registered and resolved using StructureMap. I then have an abstract factory to load additional families of products at runtime.
If I have a StructureMap registries like this one:
public ProductAClaimsRegistry()
{
var name = InstanceKeys.ProductA;
this.For<IClaimsDataAccess>().LifecycleIs(new UniquePerRequestLifecycle()).Use<ProductAClaimsDataAccess>().Named(name)
.Ctor<Func<DbConnection>>().Is(() => new SqlConnection(ConfigReader.ClaimsTrackingConnectionString));
this.For<IClaimPreparer>().LifecycleIs(new UniquePerRequestLifecycle()).Use<ProductAClaimPreparer>().Named(name);
this.For<IHistoricalClaimsReader>().LifecycleIs(new UniquePerRequestLifecycle()).Use<ProductAHistoricalClaimReader>().Named(name);
this.For<IProviderClaimReader>().LifecycleIs(new UniquePerRequestLifecycle()).Use<ProductAProviderClaimReader>().Named(name);
}
There may be a version for ProductB, ProductC and so on.
My abstract factory then loads the correct named instance like this:
public abstract class AbstractClaimsFactory
{
private IClaimsReader claimsReader;
private IClaimPreparer claimPreparer;
protected string InstanceKey { get; set; }
public virtual IClaimsReader CreateClaimReader()
{
return this.claimsReader;
}
public virtual IClaimPreparer CreateClaimPreparer()
{
return this.claimPreparer;
}
public void SetInstances()
{
this.CreateInstances();
var historicalReader = ObjectFactory.Container.GetInstance<IHistoricalClaimsReader>(this.InstanceKey);
var providerReader = ObjectFactory.Container.GetInstance<IProviderClaimReader>(this.InstanceKey);
this.claimsReader = new ClaimsReader(historicalReader, providerReader);
this.claimPreparer = ObjectFactory.Container.GetInstance<IClaimPreparer>(this.InstanceKey);
}
protected abstract void CreateInstances();
}
At runtime there is a processor class that has a concrete factory injected like this:
public void Process(AbstractClaimsFactory claimsFactory)
{
// core algorithm implemented
}
A concrete factory then exists for each product:
public class ProductAClaimsFactory : AbstractClaimsFactory
{
public ProductAClaimsFactory()
{
SetInstances();
}
protected override void CreateInstances()
{
InstanceKey = InstanceKeys.ProductA;
}
}
EDIT
The classes loaded in the factory are used by other classes that are Product agnostic - but they need to inject ProductA or ProductB behaviour.
public ClaimsReader(IHistoricalClaimsReader historicalClaimsReader, IProviderClaimReader providerClaimsReader)
{
this.historicalClaimsReader = historicalClaimsReader;
this.providerClaimsReader = providerClaimsReader;
}
I'm not exactly sure if this a text book abstract factory pattern and I'm new to StructureMap and more advance DI in general.
With this solution I think I have enforced a core algorithm and reused code where appropriate.
I also think that it is extensible as ProductN can easily be added without changing existing code.
The solution also has very good code coverage and the tests are very simple.
So, bottom line is: I am fairly happy with this solution but a colleague has questioned it, specificly around using ObjectFactory.Container.GetInstance<IClaimPreparer>(this.InstanceKey); to load named instances and he said it looks like the Service Locator anti pattern.
Is he correct?
If so, can anyone point out the downsides of this solution and how I might go about improving it?
This is service location. It's a problem as you have introduced a dependency on your service locator, ObjectFactory, rather than the interface, IClaimPreparer, your AbstractClaimsFactory class actually needs. This is going to make testing harder as you'll struggle to fake an implementation of IClaimPreparer. It also clouds the intention of your class as the class's dependencies are 'opaque'.
You need to look into the use of a Composition Root to resolve the anti-pattern. Have a look at Mark Seemann's work to find out more.
He's partially correct. Given a good DI container it is possible to register all your components and resolve the root object in your object tree... the DI container handles creating all the dependency for the root object (recursively) and creates the whole object tree for you. Then you can throw the DI container away. The nice thing about doing it that way is all references to DI container are confined to the entry-point of your app.
However, you are at least one step ahead of the curve since you didn't resolve dependencies in the constructor (or somewhere else) of the object using them, but instead resolved those in the factory and passed them in to the objects that need them via constructor-injection ;) (That's something I see often in code I work on and that is definitely an anti-pattern.
Here's a bit more about service locators and how they can be an anti-pattern:
http://martinfowler.com/articles/injection.html
http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/
Here's a bit more about the configure-resolve-release type pattern I hinted at:
http://blog.ploeh.dk/2010/08/30/Dontcallthecontainer;itllcallyou/
http://kozmic.net/2010/06/20/how-i-use-inversion-of-control-containers/
I've been reading up on how to write testable code and stumbled upon the Dependency Injection design pattern.
This design pattern is really easy to understand and there is really nothing to it, the object asks for the values rather then creating them itself.
However, now that I'm thinking about how this could be used the application im currenty working on I realize that there are some complications to it. Imagine the following example:
public class A{
public string getValue(){
return "abc";
}
}
public class B{
private A a;
public B(A a){
this.a=a;
}
public void someMethod(){
String str = a.getValue();
}
}
Unit testing someMethod () would now be easy since i can create a mock of A and have getValue() return whatever I want.
The class B's dependency on A is injected through the constructor, but this means that A has to be instantiated outside the class B so this dependency have moved to another class instead. This would be repeated many layers down and on some point instantiation has to be done.
Now to the question, is it true that when using Dependency Injection, you keep passing the dependencys through all these layers? Wouldn't that make the code less readable and more time consuming to debug? And when you reach the "top" layer, how would you unit test that class?
I hope I understand your question correctly.
Injecting Dependencies
No we don't pass the dependencies through all the layers. We only pass them to layers that directly talk to them. For example:
public class PaymentHandler {
private customerRepository;
public PaymentHandler(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
public void handlePayment(CustomerId customerId, Money amount) {
Customer customer = customerRepository.findById(customerId);
customer.charge(amount);
}
}
public interface CustomerRepository {
public Customer findById(CustomerId customerId);
}
public class DefaultCustomerRepository implements CustomerRepository {
private Database database;
public CustomerRepository(Database database) {
this.database = database;
}
public Customer findById(CustomerId customerId) {
Result result = database.executeQuery(...);
// do some logic here
return customer;
}
}
public interface Database {
public Result executeQuery(Query query);
}
PaymentHandler does not know about the Database, it only talks to CustomerRepository. The injection of Database stops at the repository layer.
Readability of the code
When doing manual injection without framework or libraries to help, we might end up with Factory classes that contain many boilerplate code like return new D(new C(new B(), new A()); which at some point can be less readable. To solve this problem we tend to use DI frameworks like Guice to avoid writing so many factories.
However, for classes that actually do work / business logic, they should be more readable and understandable as they only talk to their direct collaborators and do the work they need to do.
Unit Testing
I assume that by "Top" layer you mean the PaymentHandler class. In this example, we can create a stub CustomerRepository class and have it return a Customer object that we can check against, then pass the stub to the PaymentHandler to check whether the correct amount is charged.
The general idea is to pass in fake collaborators to control their output so that we can safely assert the behavior of the class under test (in this example the PaymentHandler class).
Why interfaces
As mentioned in the comments above, it is more preferable to depend on interfaces instead of concrete classes, they provide better testability(easy to mock/stub) and easier debugging.
Hope this helps.
Well yes, that would mean you have to pass the dependencies over all the layers. However, that's where Inversion of Control containers come in handy. They allow you to register all components (classes) in the system. Then you can ask the IoC container for an instance of class B (in your example), which would automatically call the correct constructor for you automatically creating any objects the constructor depends upon (in your case class A).
A nice discussion can be found here: Why do I need an IoC container as opposed to straightforward DI code?
IMO, your question demonstrates that you understand the pattern.
Used correctly, you would have a Composition Root where all dependencies are resolved and injected. Use of an IoC container here would resolve dependencies and pass them down through the layers for you.
This is in direct opposition to the Service Location pattern, which is considered by many as an anti-pattern.
Use of a Composition Root shouldn't make your code less readable/understandable as well-designed classes with clear and relevant dependencies should be reasonably self-documenting. I'm not sure about unit testing a Composition Root. It has a discreet role so it should be testable.
In wanting to get some hands-on experience of good OO design I've decided to try to apply separation of concerns on a legacy app.
I decided that I wasn't comfortable with these calls being scattered all over the code base.
ConfigurationManager.AppSettings["key"]
While I've already tackled this before by writing a helper class to encapsulate those calls into static methods I thought it could be an opportunity to go a bit further.
I realise that ultimately I should be aiming to use dependency injection and always be 'coding to interfaces'. But I don't want to take what seems like too big a step. In the meantime I'd like to take smaller steps towards that ultimate goal.
Can anyone enumerate the steps they would recommend?
Here are some that come to mind:
Have client code depend on an interface not a concrete implementation
Manually inject dependencies into an
interface via constructor or property?
Before going to the effort of
choosing and applying an IoC
container how do I keep the code
running?
In order to fulfil a dependency the default
constructor of any class that needs a
configuration value could use a Factory
(with a static CreateObject() method)?
Surely I'll still have a concrete dependency on the Factory?...
I've dipped into Michael Feathers' book so I know that I need to introduce seams but I'm struggling to know when I've introduced enough or too many!
Update
Imagine that Client calls methods on WidgetLoader passing it the required dependencies (such as an IConfigReader)
WidgetLoader reads config to find out what Widgets to load and asks WidgetFactory to create each in turn
WidgetFactory reads config to know what state to put the Widgets into by default
WidgetFactory delegates to WidgetRepository to do the data access, which reads config to decide what diagnostics it should log
In each case above should the IConfigReader be passed like a hot potato between each member in the call chain?
Is a Factory the answer?
To clarify following some comments:
My primary aim is to gradually migrate some app settings out of the config file and into some other form of persistence. While I realise that with an injected dependency I can Extract and Override to get some unit testing goodness, my primary concern is not testing so much as to encapsulate enough to begin being ignorant of where the settings actually get persisted.
When refactoring a legacy code-base you want to iteratively make small changes over time. Here is one approach:
Create a new static class (i.e. MyConfigManager) with a method to get the app setting (i.e. GetAppSettingString( string key )
Do a global search and replace of "ConfigurationManager.AppSettings["key"] and replace instances with "MyConfigManager.GetAppSettingsString("key")"
Test and check-in
Now your dependency on the ConfigurationManager is in one place. You can store your settings in a database or wherever, without having to change tons of code. Down side is that you still have a static dependency.
Next step would be to change MyConfigManager into a regular instance class and inject it into classes where it is used. Best approach here is to do it incrementally.
Create an instance class (and an interface) alongside the static class.
Now that you have both, you can refactor the using classes slowly until they are all using the instance class. Inject the instance into the constructor (using the interface). Don't try for the big bang check-in if there are lots of usages. Just do it slowly and carefully over time.
Then just delete the static class.
Usually its very difficult to clean a legacy application is small steps, because they are not designed to be changed in this way. If the code is completely intermingled and you have no SoC it is difficult to change on thing without being forced to change everything else... Also it is often very hard to unit test anything.
But in general you have to:
1) Find the simplest (smallest) class not refactored yet
2) Write unit tests for this class so that you have confidence that your refactoring didn't break anything
3) Do the smallest possible change (this depends on the project and your common sense)
4) Make sure all the tests pass
5) Commit and goto 1
I would like to recommend "Refactoring" by Martin Fowler to give you more ideas: http://www.amazon.com/exec/obidos/ASIN/0201485672
For your example, the first thing I'd do is to create an interface exposing the functionality you need to read config e.g.
public interface IConfigReader
{
string GetAppSetting(string key);
...
}
and then create an implementation which delegates to the static ConfigurationManager class:
public class StaticConfigReader : IConfigReader
{
public string Get(string key)
{
return ConfigurationManager.AppSetting[key];
}
}
Then for a particular class with a dependency on the configuration you can create a seam which initially just returns an instance of the static config reader:
public class ClassRequiringConfig
{
public void MethodUsingConfig()
{
string setting = this.GetConfigReader().GetAppSetting("key");
}
protected virtual IConfigReader GetConfigReader()
{
return new StaticConfigReader();
}
}
And replace all references to ConfigManager with usages of your interface. Then for testing purposes you can subclass this class and override the GetConfigReader method to inject fakes so you don't need any actual config file:
public class TestClassRequiringConfig : ClassRequiringConfig
{
public IConfigReader ConfigReader { get; set; }
protected override IConfigReader GetConfigReader()
{
return this.ConfigReader;
}
}
[Test]
public void TestMethodUsingConfig()
{
ClassRequiringConfig sut = new TestClassRequiringConfig { ConfigReader = fakeConfigReader };
sut.MethodUsingConfig();
//Assertions
}
Then eventually you will be able to replace this with property/constructor injection when you add an IoC container.
EDIT:
If you're not happy with injecting instances into individual classes like this (which would be quite tedious if many classes depend on configuration) then you could create a static configuration class, and then allow temporary changes to the config reader for testing:
public static class Configuration
{
private static Func<IConfigReader> _configReaderFunc = () => new StaticConfigReader;
public static Func<IConfigReader> GetConfiguration
{
get { return _configReaderFunc; }
}
public static IDisposable CreateConfigScope(IConfigReader reader)
{
return new ConfigReaderScope(() => reader);
}
private class ConfigReaderScope : IDisposable
{
private readonly Func<IConfigReader> _oldReaderFunc;
public ConfigReaderScope(Func<IConfigReader> newReaderFunc)
{
this._oldReaderFunc = _configReaderFunc;
_configReaderFunc = newReaderFunc;
}
public void Dispose()
{
_configReaderFunc = this._oldReaderFunc;
}
}
}
Then your classes just access the config through the static class:
public void MethodUsingConfig()
{
string value = Configuration.GetConfigReader().GetAppSetting("key");
}
and your tests can use a fake through a temporary scope:
[Test]
public void TestMethodUsingConfig()
{
using(var scope = Configuration.CreateConfigScope(fakeReader))
{
new ClassUsingConfig().MethodUsingConfig();
//Assertions
}
}