I have a question about the best way to design classes in order to be test-friendly. Suppose I have an OrderService class, which is used to place new orders, check the status of orders, and so on. The class will need to access customer information, inventory information, shipping information, etc. So the OrderService class will need to use CustomerService, InventoryService, and ShippingService. Each service also has its own backing repository.
What is the best way to design the OrderService class to be easily testable? The two commonly used patterns that I've seen are dependency injection and service locator. For dependency injection, I'd do something like this:
class OrderService
{
private ICustomerService CustomerService { get; set; }
private IInventoryService InventoryService { get; set; }
private IShippingService ShippingService { get; set; }
private IOrderRepository Repository { get; set; }
// Normal constructor
public OrderService()
{
this.CustomerService = new CustomerService();
this.InventoryService = new InventoryService();
this.ShippingService = new ShippingService();
this.Repository = new OrderRepository();
}
// Constructor used for testing
public OrderService(
ICustomerService customerService,
IInventoryService inventoryService,
IShippingService shippingService,
IOrderRepository repository)
{
this.CustomerService = customerService;
this.InventoryService = inventoryService;
this.ShippingService = shippingService;
this.Repository = repository;
}
}
// Within my unit test
[TestMethod]
public void TestSomething()
{
OrderService orderService = new OrderService(
new FakeCustomerService(),
new FakeInventoryService(),
new FakeShippingService(),
new FakeOrderRepository());
}
The disadvantage to this is that every time I create an OrderService object that I'm using in a test, it takes a lot of code to call the constructor within my tests. My Service classes also end up with a bunch of properties for each Service and Repository class that they use. And as I expand my program and add more dependencies between various Service and Repository classes, I have to go back and add more and more parameters to constructors of classes that I've already made.
For a service locator pattern, I could do something like this:
class OrderService
{
private CustomerService CustomerService { get; set; }
private InventoryService InventoryService { get; set; }
private ShippingService ShippingService { get; set; }
private OrderRepository Repository { get; set; }
// Normal constructor
public OrderService()
{
ServiceLocator serviceLocator = new ServiceLocator();
this.CustomerService = serviceLocator.CreateCustomerService()
this.InventoryService = serviceLocator.CreateInventoryService();
this.ShippingService = serviceLocator.CreateShippingService();
this.Repository = serviceLocator.CreateOrderRepository();
}
// Constructor used for testing
public OrderService(IServiceLocator serviceLocator)
{
this.CustomerService = serviceLocator.CreateCustomerService()
this.InventoryService = serviceLocator.CreateInventoryService();
this.ShippingService = serviceLocator.CreateShippingService();
this.Repository = serviceLocator.CreateOrderRepository();
}
}
// Within a unit test
[TestMethod]
public void TestSomething()
{
OrderService orderService = new OrderService(new TestServiceLocator());
}
I like how the service locator pattern results in less code when calling the constructors, but it also gives less flexibility.
What's the recommended way to set up my Service classes that have dependencies on several other Services and Repositories so that they can be easily tested? Are either or both of the ways that I showed above good, or is there a better way?
Just a really quick answer to put you on the right track.
In my experience, if you aim for easily testable code you tend to end up with clean maintainable code as a nice side-effect. :-)
Some key points to remember:
The SOLID principles will really help you create good, clean, testable code.
(S + O + I) Break this Service up into smaller services that only do one thing, and will therefore only have one reason to change. At a minimum placing an order and checking the status of an order are completely different things. If you think quite deeply about it, you don't really need to follow the most obvious steps (eg. check credit->check stock->check shipping), some of these can be done out of order - but that's a whole other story that would probably require a different business model. Anyway you can use the Facade pattern to create a simplified view on top of those smaller services if you really need it.
Use an IoC container (eg unity)
Use a Mocking framework (eg Moq)
The service locator pattern is actually considered an anti-pattern/code smell - so please don't use it.
Your tests should use the same paths as you real code, so get rid of the 'Normal constructor'. The 'Constructor used for testing' in your first example is what your constructor should look like.
Do NOT instantiate the required services inside your class - they should be passed in instead, as an Interface. The IoC container will help you deal with this part. By doing this you are following the D in Solid (Dependency inversion principle)
Avoid using/referencing static classes/methods directly inside your own classes as much as possible. Here I'm talking about using things like DateTime.Now() directly, instead of wrapping them in an interface/class first.
For example here you could have a IClock interface with a GetLocalTime() method that your classes can use instead of using the system functions directly. This allows you to inject a SystemClock class at run-time and a MockClock during testing. By doing this you can gain full control of exactly what time is returned to your system/class under test. This principle obviously applies to all other static references that could return unpredictable results. I know it adds yet another thing you need to pass into your classes, but it at least makes that pre-existing dependency explicit and prevents the goal posts from continuously moving during testing (without having to resort to black magic, like MS Fakes).
This is a minor point, but your private properties here should really be fields
There is a difference between code that is "testable" and code that is loosely coupled.
The primary purpose of using DI is loose coupling. Testability is a side-benefit that is gained from loosely coupled code. But code that is testable isn't necessarily loosely coupled.
While injecting a service locator is obviously more loosely coupled than having a static reference to one, it is still not a best practice. The biggest drawback is lack of transparency of dependencies. You might save a few lines of code now by implementing a service locator and then think you are winning, but whatever is gained by doing so is lost when you actually have to compose your application. There is a distinct advantage to looking at the constructor in intellisense to determine what dependencies a class has then to locating the source code for that class to try to work out what dependencies it has.
So, as you might have guessed, I am recommending you use constructor injection. However, you also have an anti-pattern known as bastard injection in your example. The primary drawback of bastard injection is that you are tightly coupling your classes on each other by newing them up internally. This may seem innocent, but what would happen if you needed to move your services into separate libraries? There is a good chance that would cause circular dependencies in your application.
The best way to deal with this (especially when you are dealing with services and not configuration settings) is to either use pure DI or a DI container and just have a single constructor. You should also use a guard clause to ensure there is no way to create your order service without any dependencies.
class OrderService
{
private readonly ICustomerService customerService;
private readonly IInventoryService inventoryService;
private readonly IShippingService shippingService;
private readonly IOrderRepository repository;
// Constructor used for injection (the one and only)
public OrderService(
ICustomerService customerService,
IInventoryService inventoryService,
IShippingService shippingService,
IOrderRepository repository)
{
if (customerService == null)
throw new ArgumentNullException("customerService");
if (inventoryService == null)
throw new ArgumentNullException("inventoryService");
if (shippingService == null)
throw new ArgumentNullException("shippingService");
if (repository == null)
throw new ArgumentNullException("repository");
this.customerService = customerService;
this.inventoryService = inventoryService;
this.shippingService = shippingService;
this.repository = repository;
}
}
// Within your unit test
[TestMethod]
public void TestSomething()
{
OrderService orderService = new OrderService(
new FakeCustomerService(),
new FakeInventoryService(),
new FakeShippingService(),
new FakeOrderRepository());
}
// Within your application (pure DI)
public class OrderServiceContainer
{
public OrderServiceContainer()
{
// NOTE: These classes may have dependencies which you need to set here.
this.customerService = new CustomerService();
this.inventoryService = new InventoryService();
this.shippingService = new ShippingService();
this.orderRepository = new OrderRepository();
}
private readonly IOrderService orderService;
private readonly ICustomerService customerService;
private readonly IInventoryServcie inventoryService;
private readonly IShippingService shippingService;
private readonly IOrderRepository orderRepository;
public ResolveOrderService()
{
return new OrderService(
this.customerService,
this.inventoryService,
this.shippingService,
this.orderRepository);
}
}
// In your application's composition root, resolve the object graph
var orderService = new OrderServiceContainer().ResolveOrderService();
I also agree with Gordon's answer. If you have 4 service dependencies it is a code smell that your class is taking on too many responsibilities. You should consider refactoring to aggregate services to make your classes singular in responsibility. Of course, 4 dependencies is sometimes necessary, but it is always worth taking a step back to see if there is a domain concept that should be another explicit service.
NOTE: I am not necessarily saying that Pure DI is the best approach, but it can work for some small applications. When an application becomes complex, using a DI container can pay dividends by using convention-based configuration.
Related
I'm facing a problem trying to implement a unit test for a method on a service.
The architecture of the project is a little bit cumbersome, to say the less...
The problem is that within the method to test it calls another method to take an instance of another service, here is the little monster:
public void SendOrderEmail(string orderCode)
{
Order order= GetOrderService().SerachByCode(orderCode);
.... Send email with the order ....
}
private IOrderService GetOrderService()
{
return OrderService = AutofacDependencyResolver.Current.ApplicationContainer.Resolve<IOrderService>();
}
Please, don't ask why a service calls another service or why is that service not injected at the constructor, as i said the architecture of this project is weird in some points.
I just need to know what is the way to implement a unit test for a method like that.
Thank you!
I would refactor a little the code, let the class that implement this method have IOrderService injected through the constructor, save the instance and then use it,
this way you can inject your fake IOrderService during the test (or use Automock) :)
If you really really can't change the constructor, you can use a property to set IOrderService
---------------- edit
Since i got some downvote on this answer I've tried to get to understand better what is going on.
I'm not sure about this, but seems like you can't edit this class you wrote about, you just want to test it.
Well if that is the case i think i can still give you some advices.
Advice number one: make a test project, link the class file, make a new file with a class like the following one.
class AutofacDependencyResolver {
public static Current { get; private set; }
public ILifetimeScope ApplicationContainer { get; private set; }
public AutofacDependencyResolver(ILifetimeScope scope) {
Current = this;
ApplicationContainer = scope;
}
}
Since the class you need to test is linked it's gonne to compile it and you just can now achieve what you need.
The other (and i think better) advice is do not test stuff you did not wrote / can't modify. What i'm suggesting is writing an adapter, so a class that use the one you can't modify as a black box.
In this case i think you need to test the email, so just check the email output the address stuff like that and ignore the rest.
the people who wrote those classes should have followed solid principles...
As others have said, and you're probably aware yourself anyway, you really want to refactor classes like this and use constructor injection if at all possible. Service location is generally considered an anti-pattern (https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/) and it specifically makes unit testing like this harder and less transparent.
However, if you absolutely can't refactor, you can still make methods like this somewhat testable by just providing different registrations for the services you're accessing via service location.
In your case, if you have:
public class EmailSender
{
public void SendOrderEmail(string orderCode)
{
Order order = GetOrderService().SearchByCode(orderCode);
//....Send email with the order ....
}
private IOrderService GetOrderService()
{
return AutofacDependencyResolver.Current.ApplicationContainer.Resolve<IOrderService>();
}
}
...and you're looking to specifically run unit tests over SendOrderEmail to validate the logic surrounding your IOrderService implementation (which could be easily covered by a separate test), the other classes implied there might look like:
public class AutofacDependencyResolver // this is problematic but we can't change it
{
public AutofacDependencyResolver(IContainer applicationContainer)
{
ApplicationContainer = applicationContainer;
}
public IContainer ApplicationContainer { get; }
public static AutofacDependencyResolver Current { get; private set; }
public static void SetContainer(IContainer container)
{
Current = new AutofacDependencyResolver(container);
}
}
public static class ContainerProvider // this sets up production config across your app
{
public static IContainer GetProductionContainer()
{
var builder = new ContainerBuilder();
builder.RegisterType<RealOrderService>()
.As<IOrderService>();
// register all other real dependencies here
return builder.Build();
}
}
With that setup, you only need to provide mocks which are required for the specific method you're testing, assuming you can set your container within AutofacDependencyResolver easily in order to have production and test configuration running in parallel. That might look like the following, using xUnit, Moq and Autofac in a test project:
public class EmailSenderTests
{
private readonly Mock<IOrderService> _orderService;
public EmailSenderTests()
{
// to set up the test fixture we'll create a mock OrderService and store a reference to the mock itself for validation later on
_orderService = new Mock<IOrderService>();
var mockOrder = new Order();
_orderService.Setup(os => os.SearchByCode(It.IsAny<string>()))
.Returns(mockOrder);
}
private IContainer GetTestContainer()
{
// here we're adding just one registration we need, setting the mocked OrderService instance to be used for IOrderService
var builder = new ContainerBuilder();
builder.Register(c => _orderService.Object)
.As<IOrderService>();
return builder.Build();
}
[Fact]
public void SendEmail()
{
AutofacDependencyResolver.SetContainer(GetTestContainer()); // set the test container on the global singleton
var sender = new EmailSender();
sender.SendOrderEmail("abc"); // internally the email sender will retrieve the mock IOrderService via service location
// make any assertions here, e.g.
_orderService.Verify(os=>os.SearchByCode("abc"), Times.Exactly(1));
}
}
Okay so I am looking for some specific tips about Dependency Injection and how to use it.
Basically I have a MVC website which uses Ninject (and the Ninject MVC package). So when I am creating the MVC page I use constructor injection in the controllers. This is okay but IMO a bit 'ugly', but the main thing I don't like is having to pass all of the injected repositories into the other classes, it just seems a bit OTT having to pass like 6 repositories-8 repositories into a static method or object constructor.
Not to mention that on some of my pages I am having to work on almost every repository so the controller consructor gets huge and not the most manageable.
Are there any other options that wont clutter my code up as much? I don't really want to pass them in as single 'setting' objects either as that just moves the problem to a different line of code.
I also use the same class libraries for console/desktop applications. I like the idea of using DependencyResolver.Current in the class libraries but everyone says this is an anti-pattern and constructor injection should be used.
Maybe have an MyProjectDIContext class which has a dictionary which i can populate with the injected types in the controller constructors then pass the context to all methods as needed?
I have had a look for the answer bit I can't quite seem to find something that fits well.
One of the great things about Constructor Injection is that it makes design and maintainability problems more obvious. When using constructor injection, it becomes very easy to see the amount of dependencies a class has, whereas without constructor injection, a class still has the same number of dependencies, but they are tucked away.
The problem you are seeing is called Constructor Over-injection and it's a design smell, because it indicates that you are violating the Single Responsibility Principle (SRP). The SRP guides in keeping your classes small, focussed and most of all: maintainable.
Are there any other options that wont clutter my code up as much?
Absolutely: make smaller classes. MVC controllers typically get huge when we use it to group methods of a certain concept, such as 'customer' or 'order'. This however means that a controller is an ever growing class that has to be changed for any new feature that arrives. This is a violation of the Open/closed Principle that tells we should strive to have a system where we can plugin new features without having to touch existing classes.
The solution therefore is not to revert to the Service Locator anti-pattern or Property Injection, but to create smaller classes that do one particular thing. Constructor Injection should be your primary way of applying Dependency Injection, even in class libraries.
It seems that your controller is shuffling repositories to other classes. Let Ninject supply those classes to you instead:
public class Controller
{
public Controller(IDependencyFactory dependency) { }
}
public interface IDependencyFactory
{
IDependency CreateDependency();
}
public interface IDependency
{
}
public class Dependency : IDependency
{
public Dependency() { }
}
public class Program
{
public static void Main()
{
var standardKernel = new StandardKernel();
standardKernel.Bind<IDependencyFactory>().ToFactory();
standardKernel.Bind<IDependency>().To<Dependency>();
}
}
You don't have to write an implementation of IDependencyFactory, that is handled by the factory extension. Your Dependency-class will get it's dependencies injected by Ninject.
Okay I seem to have found a way to do this which doesn't seem as smelly!
I had thought that if you are for example using MVC you would get the Repositories in through the constructor and that was the only way to resolve the dependencies.
After doing some work to move sections of reusuable code into IoC friendly Interfaces and their implementations I noticed that when you create reference IMyInterface in a controller constructor the default constructor of the implementing class is run and you can pull other IoC classes such as resolved repositories from there.
This may be common knowledge but it does make things much much neater and solves the problem I was having.
Example
Controller
public IDefaultTemplateManager DefaultTemplateManager { get; set; }
public DefaultController(IDefaultTemplateManager defaultTemplateManager) {
this.DefaultTemplateManager = defaultTemplateManager;
}
public ActionResult MyAction(FormCollection collection) {
DefaultTemplateManager.Process("MyKeyHere");
View();
}
IDefaultTemplateManager
public interface IDefaultTemplateManager {
ProcessResponse Process(string UniqueKey, DefaultTemplateManagerEditMode DatabaseName, string DefaultTemplateName);
}
DefaultTemplateManager
public class DefaultTemplateManager : IDefaultTemplateManager {
protected IRepository<MyEntity1> MyEntityRepo1 { get; set; }
protected IRepository<MyEntity2> MyEntityRepo2 { get; set; }
protected IRepository<MyEntity3> MyEntityRepo3 { get; set; }
protected IRepository<MyEntity4> MyEntityRepo4 { get; set; }
protected IRepository<MyEntity5> MyEntityRepo5 { get; set; }
protected IRepository<MyEntity6> MyEntityRepo6 { get; set; }
public DefaultTemplateManager(IRepository<MyEntity1> MyEntityRepository1, IRepository<MyEntity2> MyEntityRepository2, IRepository<MyEntity3> MyEntityRepository3, IRepository<MyEntity4> MyEntityRepository4, IRepository<MyEntity5> MyEntityRepository5, IRepository<MyEntity6> MyEntityRepository6, ) {
this.MyEntityRepo1 = MyEntityRepository1;
this.MyEntityRepo2 = MyEntityRepository2;
this.MyEntityRepo3 = MyEntityRepository3;
this.MyEntityRepo4 = MyEntityRepository4;
this.MyEntityRepo5 = MyEntityRepository5;
this.MyEntityRepo6 = MyEntityRepository6;
}
public ProcessResponse Process(string UniqueKey) {
/* Do Work */
}
I have a scenario using WebApi, Generic Repository, EF6 and unit of work pattern
(in order to wrap all changes from several calls to the same context.)
Manager layer is used to perform calls to different repositories and also to other managers.
Currently Customer Manager does inject both repos and other Managers like:
public class CustomerManager {
public CustomerManager(IRepository<Customer> _customerRepository, IRepository<Order> orderRepository, IManager itemManager) {
_orderReporsitory = orderReporsitory;
_itemManager = itemManager;
_customerRepository = customerRepository;
}
public bool Save(Customer customer) {
_orderReporsitory.Find...
_itemManager.IsItemUnique(ItemId)
_customerRepository.Save(customer);
}
}
This code does not compile, for reference only.
Approaches like this
http://blog.longle.net/2013/05/11/genericizing-the-unit-of-work-pattern-repository-pattern-with-entity-framework-in-mvc/
Will wrap several repositories under a unit of work and flush the changes all together.
My issue involves also adding another Manager layer, to be wrapped also inside unit of work and allow both calls to repositories and other managers
(as I want to reuse some manager logic. Like in the example, I am re-using some ItemManager logic)
This code https://stackoverflow.com/a/15527444/310107
using (var uow = new UnitOfWork<CompanyContext>())
{
var catService = new Services.CategoryService(uow);
var custService = new Services.CustomerService(uow);
var cat = new Model.Category { Name = catName };
catService.Add(dep);
custService.Add(new Model.Customer { Name = custName, Category = cat });
uow.Save();
}
is using something similar of what I need but I would also like to be able to inject the services to unit test them (and not creating instances in the body of my manager/service method)
What would the best approach to do this ?
Thanks
Your code snippet with the unit of work has several problems, such as:
You create and dispose the unit of work explicitly within that method, forcing you to pass along that unit of work from method to method and class to class.
This causes you to violate the Dependency Inversion Principle, because you now depend on concrete types (CategoryService and CustomerService), which complicates your code and makes your code harder to test.
If you need to change the way the unit of work is created, managed or disposed, you will have to make sweeping changes throughout the application; A violation of the Open/Closed Principle.
I expressed these problems in more details in this answer.
Instead, I propose to have one DbContext, share it through a complete request, and control its lifetime in the application's infrastructure, instead of explicitly throughout the code base.
A very effective way of doing this is by placing your service layer behind a generic abstaction. Although the name of this abstraction is irrelevant, I usually call this abstraction 'command handler:
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
There are a few interesting things about this abstaction:
The abstraction describes one service operation or use case.
Any arguments the operation might have are wrapped in a single message (the command).
Each operation gets its own unique command class.
Your CustomerManager for instance, might look as follows:
[Permission(Permissions.ManageCustomerDetails)]
public class UpdateCustomerDetailsCommand {
public Guid CustomerId { get; set; }
[Required] public string FirstName { get; set; }
[Required] public string LastName { get; set; }
[ValidBirthDate] public DateTime DateOfBirth { get; set; }
}
public class UpdateCustomerDetailsCommandHandler
: ICommandHandler<UpdateCustomerDetailsCommand> {
public UpdateCustomerDetailsCommandHandler(
IRepository<Customer> _customerRepository,
IRepository<Order> orderRepository,
IManager itemManager) {
_orderReporsitory = orderReporsitory;
_itemManager = itemManager;
_customerRepository = customerRepository;
}
public void Handle(UpdateCustomerDetailsCommand command) {
var customer = _customerRepository.GetById(command.CustomerId);
customer.FirstName = command.FirstName;
customer.LastName = command.LastName;
customer.DateOfBirth = command.DateOfBirth;
}
}
This might look like just a bunch of extra code, but having this message and this generic abstraction allows us to easily apply cross-cutting concerns, such as handling the unit of work for instance:
public class CommitUnitOfWorkCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand> {
private readonly IUnitOfWork unitOfWork;
private readonly ICommandHandler<TCommand> decoratee;
public CommitUnitOfWorkCommandHandlerDecorator(
IUnitOfWork unitOfWork,
ICommandHandler<TCommand> decoratee) {
this.unitOfWork = unitOfWork;
this.decoratee = decoratee;
}
public void Handle(TCommand command) {
this.decoratee.Handle(command);
this.unitOfWork.SaveChanges();
}
}
The class above is a decorator: It both implements ICommandHandler<TCommand> and it wraps ICommandHandler<TCommand>. This allows you to wrap an instance of this decorator around each command handler implementation and allow the system to transparently save the changes made in the unit of work, without any piece of code having to do this explicitly.
It is also possible to create a new unit of work here, but the easiest thing to start with is to let the unit of work live for the duration of the (web) request.
This decorator will however just be the beginning of what you can do with decorators. For instance, it will be trivial to:
Apply security checks
Do user input validation
Run the operation in a transaction
Apply a deadlock retry mechanism.
Prevent reposts by doing deduplication.
Register each operation in an audit trail.
Store commands for queuing or background processing.
More information can be found in the articles, here, here and here.
Getting more and more familiar with DI but I still have few niggles.
Read few articles where it says "Injection must be done at the entry point"
Suppose I have a situation where we have wcf Services and these are used both by internal win/web application and external third parties uses those wcf services.
Now where do you inject the Services and repositories?
Above to me seems to be a common scenarios!
Also i pass all those interfaces around.(Very good for mocking) how do I stop somebody from calling EG my repository from a layer that should NOT be calling the repository.
EG only the business Layer should call DAL.
Now by injecting a IRepository into a controller nothing stops a developer from calling the DAL.
Any suggestion? Links that clear all this
Noddy example of my poor man DI. How do I do the same using unity and Injecting all at the entryPoint?
[TestFixture]
public class Class1
{
[Test]
public void GetAll_when_called_is_invoked()
{
var mockRepository = new Mock<ICustomerRepository>();
mockRepository.Setup(x => x.GetAll()).Verifiable();
new CustomerService(mockRepository.Object);
ICustomerBiz customerBiz = new CustomerBizImp(mockRepository.Object);
customerBiz.GetAll();
mockRepository.Verify(x=>x.GetAll(),Times.AtLeastOnce());
}
}
public class CustomerService : ICustomerService //For brevity (in real will be a wcf service)
{
private readonly ICustomerRepository _customerRepository;
public CustomerService(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
public IEnumerable<Customer> GetAll()
{
return _customerRepository.GetAll();
}
}
public class CustomerBizImp : ICustomerBiz
{
private readonly ICustomerRepository _customerRepository;
public CustomerBizImp(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
public IEnumerable<Customer> GetAll()
{
return _customerRepository.GetAll();
}
}
public class CustomerRepository : ICustomerRepository
{
public IEnumerable<Customer> GetAll()
{
throw new NotImplementedException();
}
}
public interface ICustomerRepository
{
IEnumerable<Customer> GetAll();
}
public interface ICustomerService
{
IEnumerable<Customer> GetAll();
}
public interface ICustomerBiz
{
IEnumerable<Customer> GetAll();
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
thanks
This is a blog post on Composition roots or what you call entry points. Its from Mark Seemann the author of Dependency Injection in .NET. If you are looking for a deep understanding of DI this book is a must read.
There are a lot of samples out there on how to combine WCF and DI. If you are hosting your services in IIS you would need to write a custom ServiceHostFactory where you initialize you DI container. This is a sample for Microsoft's Unity.
As to
how do I stop somebody from calling EG my repository from a layer that should NOT be calling the repository
Do you use poor man's DI and pass all your references around through all your layers? Then you should definitely consider using a DI/IoC container like StructureMap, Castle Windsor, AutoFac or Unity.
If you are asking "how can I in general avoid the situation that someone does not follow my layer boundaries": Write tests that fail if an assembly references another one it should not reference (e.g. UI should not reference DAL).
UPDATE
I assume you wanted the service to use ICustomerBiz instead of the ICustomerRepository. If that is right the setup for Unity would look like this:
[TestMethod]
public void GetAll_with_Unity()
{
var container = new UnityContainer();
container.RegisterType<ICustomerRepository, CustomerRepository>();
container.RegisterType<ICustomerBiz, CustomerBizImp>();
container.RegisterType<ICustomerService, CustomerService>();
var svc = container.Resolve<ICustomerService>();
var all = svc.GetAll();
Assert.AreEqual(1, all.Count());
}
DI is much more about injecting a dependency inside your dipendency architecture, that's why it can not resolve, as is, layers isolation problem you face.
Production code can and should contain DI code, if it needed.
If we are talking about plugin-based architectureDI is one of most natural choices out there.
if we are talking about app behaviour change, like for example Logging system choice: save on remote server if connection present if not injject local logger for future sync with the server.
There are plenty of usages of DI in production, but all that is up to Architect to decide when, how and if use it.
In other words, there is no single rule of it use, it's not a hummer for any nail, so use it where you think it's approriate and use it wisely.
I am looking at depency injection, I can see the benefits but I am having problems with the syntax it creates. I have this example
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
The problem is that I don't want to write
BusinessProducts bp = new BusinessProducts(dataContextImplementation);
I would continue to write
BusinessProducts bp = new BusinessProducts();
because I feel the first alternative just feels unatural. I dont want to know what the BusinessProduct "depends" on to get the products, also I feel it makes my code more unreadable.
Is there any alternatives to this approach as I would like to keep my original syntax for creating objects but I would like to still be able to fake the dependencies when unit testing or is it this dependecy injection frameworks can do for me?
I am coding in c# but alternatives from other languages is welcome
I use a factory for my context and inject it, providing a suitable default if the provided factory is null. I do this for two reasons. First, I use the data context as a unit of work scoped object so I need to be able to create them when needed, not keep one around. Second, I'm primarily using DI to increase testability, with decoupling only a secondary consideration.
So my business products class would look like:
public class BusinessProducts
{
private IDataContextFactory DataContextFactory { get; set; } // my interface
public BusinessProducts() : this(null) {}
public BusinessProducts( IDataContextFactory factory )
{
this.DataContext = factory ?? new BusinessProductsDataContextFactory();
}
public void DoSomething()
{
using (DataContext dc = this.DataContextFactory().CreateDataContext())
{
...
}
}
An alternative to this would be to make the factory property publicly settable and inject an alternate factory by setting the property. Either way if you want to keep the null constructor, you'll need to provide a default.
You can create a factory. DI containers are best for wirings that happen at setup-time - not at runtime (As this looks to be a case of). Factories can be implemented in different ways, depending on how pluggable it needs to be, and how many places you need to use it.
I would usually have an empty constructor which uses a solid instance( or an instances created by IoC), amd one with DI. i.e.
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = new SolidDataContext();
}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
}
This way you can use DI for overriding the default instance in unit testing testing.
Your feelings, while valid, are misplaced.
The Dependency Injection pattern is a direct application of the Inversion of Control principle.
This means that, instead of your class controlling the instances of other classes it consumes, that relationship is inverted and the dependencies are provided to it.
As such, your classes naturally expose their dependencies via constructor arguments or properties. Showing disdain for this structure says you haven't truly grokked the pattern.
There are two distinct cases here:
In production code you will never write
new BusinessProducts(dataContextImplementation)
because dependency injection will normally be creating the full object hierarchy for you. This is the "viral" nature of dependency injection patterns, they tend to take over full control of your service creation.
In unit test code you will normally be creating this yourself, but quite often you will be supplying a mock object or a stub implementation of dataContextImplementation. So normally you will be injecting an object that does not have a large number of subsequent dependencies.
http://springframework.net/ and http://structuremap.sourceforge.net/Default.htm are probably the mostly used DI frameworks for .NET based languages and will both do what you need.
Generally the framework itself will have the logic to build up the entire object tree. For example, instead of
new SomeObjectO(diContext)
you would call the framework like this:
DIFramework.GetNew<SomeObjectO>();
or
DIFramework.Get<SomeObject>();
Another interesting framework to take a look at if you would like to learn about DI and the process is Microsoft's Unity and Object Builder projects.
If you really do not like injecting this instance in the constructor, you might try to use the CommonServiceLocator with your favourite compatible .NET depedency injection framework. This would allow you to write code like this:
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDataContext>();
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
However, please beware that this is not what most people would expect when they know that you use a dependency injection framework. I think that it is much more common to use a dependency injection framework and letting it create all objects for you.
BusinessProducts bp = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<BusinessProducts>();
If you would like to avoid the dependeny injection framework path, using a factory is probably the best way to go.
There's a technique called poor man's DI that looks like this
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts() : this(new DataContext()) {}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
This is not ideal since it ties you to the implementation but its a good stepping stone towards decoupled code. this is similar to #tvanfosson but a lot simplier.
I second the recommendation for Windsor
My code will reference Microsoft Unity but I am sure it is pretty applicable to all DI frameworks. If you're using DI correctly you never need to call new BusinessObject(new dataContext) the DI association will handle it all for you.
My example will be a little bit long since I will paste in some code I use for running a Model View Presenter website fully DI loaded by Unity. (If you want the full source check out my blog and download it from my Assembla SVN server)
Load the container (can be in code like I prefer or using configuration)
protected void Application_Start(object sender, EventArgs e)
{
Application.GetContainer()
// presenters / controllers are per request
.RegisterType<IEmployeeController, EmployeeController>(new ContextLifetimeManager<IEmployeeController>())
//Data Providers are Per session
.RegisterType<IEmployeeDataProvider, EmployeeDataProvider>(new SessionLifetimeManager<IEmployeeDataProvider>())
//Session Factory is life time
.RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());
}
Custom HTTP module calls Unity BuildUp Method for each page during the OnPreRequest invocation.
private static void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
var handler = HttpContext.Current.Handler;
HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler);
// User Controls are ready to be built up after the page initialization is complete
var page = HttpContext.Current.Handler as Page;
if (page != null)
{
page.InitComplete += OnPageInitComplete;
}
}
Page container presenter decorated with [Dependency] attribute
public partial class Employees : Page, IEmployeeView
{
private EmployeePresenter _presenter;
[Dependency]
public EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
}
Presenter with InjectionConstructor method
public class EmployeePresenter : Presenter<IEmployeeView>
{
private readonly IEmployeeController _controller;
[InjectionConstructor]
}
public EmployeePresenter(IEmployeeController controller)
{
_controller = controller;
}
Controller follows suit
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Same with provider
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Lastly the session manager, which contains only a regular constructor.
public class NHibernateSessionManager : INHibernateSessionManager
{
private readonly ISessionFactory _sessionFactory;
public NHibernateSessionManager()
{
_sessionFactory = GetSessionFactory();
}
}
So what happens when a page request is started the BuildUp() method is called on the page by the HttpModule. Unity then sees the Property marked with the Dependency attribute and will check it's container to see if inside it exists an EmployeePresenter object.
Since there is no such object in the container it will then try to create an EmployeePresenter. Upon inspection to create the class it sees inside the Presenter it requires a constructor that needs a IEmployeeController injected into it. Since the container actually has a manager for the controller it will see if an instance of it exists in the container which on the beginning of the page request doesn't exist, so it will go to instantiate the controller.
Unity will then see the controller requires a IEmployeeDataProvider injected into it, and it will continue on this process until it finally gets to the point where the Provider needs the session manager injected. Since the session manager has no more need for injection Unity will then create an instance of the session manager store it in the container for it's given ContainerLifeTimeManager, inject it into the Provider and store that instance, and so on down to where it finished creating a EmployeePresenter dependency for the page.
you can also look at windsor for IoC .