Hello, I'm trying to implement a ViewModelFactory "pattern" and I was wondering what's the best way to achieve it, considering the constraints of the current IoC container.
public class UserCreateViewModelFactory
{
private readonly DbContext db;
public UserCreateViewModelFactory(DbContext db){ this.db = db;}
public void Create(CreateUserViewModel viewModel)
{
//Creates the user
}
}
I have the above class easily injected into my controllers ctor. The head ache will come when I need more ViewModelBuilders, So I want to avoid two things:
Bloat ctor with injections
Bloat container with registrations
I want to be able to inject an IViewModelFactory on my controller and then using it like this:
[HttpGet]
public IActionResult GetUsers(int id)
{
return View(viewModelFactory.Build<GetUserViewModel>(id));
}
Notice that on calling Build(T) it has to call the correct IViewModelFactory implementation.
I know that StructureMap container support binding the concrete implementations to the corresponding interface but I'm trying to come up with a solution without having to add another dependecy to the project.
I think if you have builders for building viewmodels, then factory is extra layer of abstraction which simply can be dropped off.
Because you know the type of created viewmodel at compile time you can just inject a builder you need to the controller constructor.
If your controller create a lot of viewmodels and you end up with a lot of builders you need to inject - this can be considered as a sign of violation of Single Responsibility Principle. In that case you need to separate logic of controller to different controllers.
So I want to avoid two things:
Bloat ctor with injections
Separate class with bloated constructor to another classes with more specific responsibility which takes smaller amount of dependencies.
Or wrap dependencies with one or two, three classes based on their relation
Bloat container with registrations
This cannot be a problem, because dependency containers is usually designed to register whole "object graph" of your application
After sometime researching, I finally came up with a good solution for the this problem.
The solution is basically extending the default IoC capabilities through an IServiceCollection.ConnectImplementations() extension method.
During registration I'll search my concrete classes and connect them with its respective interfaces (like other containers). Then I use a Mediator/Proxy that has IServiceCollection injected and knows which concrete class should be building the view model.
The full solution is better explained by this gist I've created.
Related
Generally speaking, my dependencies are abstracted to interfaces, but I will only be using one concrete implementation during non-testing use. For example, were I to write a FooService:
public class FooService : IFooService
{
private readonly IBarDependency _barDependency;
public FooService(IBarDependency barDependency)
{
this._barDependency = barDependency;
}
public FooService() : this (new BarDependency())
{
// nothing to do here
}
. . . // code goes here
}
Now purists tend to gasp in horror, because I instantiated a concrete class in the parameterless constructor. I have, in the past, shrugged this off, because I know the only time I will not be using the concrete class is when I am unit testing and mocking dependencies.
While it does couple the FooService class to the BarDependency class, it's not a tight coupling; these classes and interfaces also exist in the same assembly, so it doesn't seem to me like I'm losing a whole lot here, or painting myself into a corner. I can still easily test the FooService class without getting unmanageable code, just by using the constructor that allows me to pass in mocked interfaces.
So the question is: what is actually at risk here? What am I losing with this sort of pattern that is worth adding an IoC container?
Lifetime management, for example. Maybe you use BarDependency throughout your code and only want one instance to be alive. You can't do this if every user creates their own instances.
You also have to find all usages of new BarDependency() if you ever want to replace it with new NewBarDependency().
A container fixes both problems for you, as then you configure the instantiation and lifecycle of objects in one method, namely where you set up your container.
It depends, but if the FooService needs to be accessed by some other developer, the dependency to BarDependency will be basically hidden. In my opinion not only mocking and testing is the reason for using dependency injection, but also a clear indication what is used by certaing classes, and what they are need to work properly.
And maybe I'm to much purist, but when such pattern is ok, then it's easily to go further and end up with a totally tightly coupled and hard maintanable code.
What you lose without dependency injection is the ability to centralize all aspects of the dependency management. Visualizing the dependency graph and managing the lifecycles of your objects is easier when you have all the information in one place, instead of scattered all over the code.
A concrete example would be if you wanted to replace the default implementation of IBarDependency used in some, but not all of the classes. Reasoning about which ones to replace is much easier if the dependencies are all wired in the same file or group of files.
What is best way to get injections in base controller when using C# StructureMap.Mvc?
I can think of these 2 ways and don't know which is better.
From controller arguments to base controller arguments
(Nice approach but becomes a mess when there are many controllers with many properties to be injected)
Don't use child controller and initiate all injections using ObjectFactory.CreateInstance() in base controller constructor
(Very less code and manageable but not considered as good practice when Controller Injection is available)
thanks in advance.
I think bother approaches are fine and you can use the mix of both. Of course depending in the situation.
A. I believe if your child Controller require a dependency to be injected, then use the Constructor injection. This way you Controller's constructor API is explicit and it should state what has been injected into the Controller. Easy to read, and easy for discoverability. If you try to hide your DI types in a factory you lose this nice API/discoverability. Use property injection when the dependencies are optional if you think so. You don't really have pass these to the base Controller unless all your Child Controllers use them.
If you think you overloading the types in your Controller, try to aggreagate those interfaces to a single types.
B. It is not advisable to directly use the Structure map ObjectFactory in your Controller. Your Controllers should be agnostics of any infrastructure DI work. You can make use a generic factory (in infrastructure) to create types which uses the ObjectFactory within. If your DI types are required by the base Controller you may use this factory to resolve those types.
The ideas, inject types only when/where they need. Avoid injecting types to Controllers when they don't use/need.
Another option you available to you is setter injection via StructureMap's ObjectFactory.BuildUp() method.
It's worth mentioning that in StructureMap 3.1 the ObjectFactory has been deprecated in favour of injecting an instance of IContainer.
The examples would look like this:
StructureMap 3.0 and below:
public class BaseController {
protected IMyExampleServer MyExampleService { get; set; };
public BaseController() {
ObjectFactory.BuildUp(this);
}
....
}
StructureMap 3.1+:
public class BaseController {
protected IMyExampleServer MyExampleService { get; set; };
public BaseController(IContainer container) {
container.ObjectFactory.BuildUp(this);
}
....
}
Using StructureMap 3.1 would mean you'd only need to inject an instance of IContainer into your derived controller rather than each individual dependency that your base class requires.
It is about this (Inject the dependency)
private readonly ICustomerService _customerService;
public Billing(ICustomerService customerService)
{
_customerService = customerService;
}
versus this (Create the dependency)
private readonly ICustomerService _customerService;
public Billing()
{
_customerService = new CustomerService();
}
The latter sample so they say is bad because... it violates DI...of course nothing is injected... but what if DI would not exist, what is so bad that the CustomerService is created manually from the Billing class? I see no practical advantage concerning exchangeability of the Service interface.
I ask for a practical example with source code may it be a unit test or showing a practical solution why it is so much more loose coupling.
Anyone keen enough to show his DI muscles and why it has a practical right to exist and be applied?
UPDATE
So people have not to read all up I will write here my short experience:
DI as a pattern has a practical usage. To follow DI by not injecting all services manually (a poor mans DI tool so they say...) use a DI framework like LightCore/Unity but be sure you use the right tool for the appropriate job. This is what I did not;-) Developing a mvvm/wpf application I have other requirements the LightCore/Unity tool could not support they even were a barrier. My solutions was to use MEFEDMVVM with which I am happy. Now my services are automatically injected at runtime not at startup time.:-)
Understanding the how and understanding the why are very different things..
One of the biggest benefits of DI is for unit testing. In your second example it's impossible to unit test Billing without also testing CustomerService (and also testing any further dependencies in the chain). In that case you're not unit testing, you're integration testing! If you want a good rationale for using DI, you need not look any further than a rationale for unit testing..
Imagine that CustomerService connects to your CRM system and your database. It creates a whole bunch of network connections to retrieve data about the customer and maybe reads additional things from the database to augment that before returning the data to the Billing class to use in its calculation.
Now you want to unit test Billing to make sure the calculations it's making are correct (you don't want to send out wrong bills right?)
How will you unit test Billing if its constructor is tied to a class that requires connections to a real CRM system and database? Wouldn't it be better to inject that dependency as an interface, easily allowing you to provide a mock version for your tests?
That is why DI is useful.
DI Comes in useful, when you want to pass different implementations of the Interface to your class, for example: Unit Testing.
Say your Billing constructor is an MVC controller's constructor, and your CustomerService took some form of IDataContext as a parameter.
Global.asax
// Does the binding
ICustomerService binds to CustomerService
IDataContext binds to EntityFrameworkContext
CustomerService
private IDataContext _datacontext;
public CustomerService(IDataContext dataContext)
{
_dataContext = dataContext;
}
public AddCustomer(Customer entity)
{
this._dataContext.Customers.Add(entity);
this._dataContext.SaveChanges;
}
MVC Controller
private ICustomerService _customerService;
public Billing(ICustomerService customerService)
{
_customerService = customerService;
}
public ActionResult NewCustomer()
{
Customer customer = new Customer(){ Name = "test" };
this._customerService.AddCustomer(customer);
return View();
}
Say you wanted to unit test your Services, or Controllers. You would pass in the CustomerServices, but you would pass in a fake implementation of the EntityFrameWorkContext.
So a FakeDbContext, that implements IDataContext, is passed to customer services.
The FakeDbContext may just store the entities in Lists or a more elaborate storage mechanism, the point being, you can inject different implementations of dependencies, which allows you to alter the behaviour of one component without having to modify your code elsewhere.
In my experience it is not only about avoiding integration test (but that is a very important point too). Instantiating classes on the inside can create a lot of work unit testing. A class like CustomerService might depend on an open Database connection, configuration files, services being available and a lot of other stuff, that you should not have to know about, when your job is to test the Billing class only.
That being said, sometimes it is a pain always to inject everything. Injection frameworks might lighten that load, but I'm not at big fan. Another kind stackoverflow user pointed me to what he called "poor mans injection". Basically it consists of two constructor overloads: One constructor with the injected interface, and one without. The one without does nothing but instantiate a concrete class that implements the interface, and pass it to the other constructor. It goes something like this:
public class Billing
{
ICustomerService _customerService;
public Billing():this(new CustomerService()) {}
public Billing(ICustomerService customerService)
{
_customerService = customerService;
}
}
This way you have an way to inject when testing AND a way to construct the class with a default implementation of the interface. Not everybody loves this pattern, but I find it practical for some scenarios.
It's often the case where I'd like to have multiple constructors in my controllers, since one of the constructors is optimal for manually injecting dependencies during unit testing and the other is optimal for using a IOC container to inject dependencies.
When using the standard service locator or DependencyResolver in MVC 3, is there any way to indicate to the controller factory which constructor to use when activating the controller?
I'd prefer not to use one of the attributes specific to an IOC framework since I want the code to remain independent of the IOC container.
UPDATE:
It seems like the majority of the answers indicate its bad practice to have multiple constructors. I don't entirely disagree with this, however, the situation arises as a result of trying to find a good solution to the mapping/conversion layer, which I asked in this question but never got a good answer to.
My code would look like this:
public class SomeController : Controller
{
private ISomeService _SomeService;
private IEntityConverter _EntityConverter;
// this would be used during unit tests when mocking the entity converter
public SomeController(ISomeService someService, IEntityConverter entityConverter)
{
_SomeService = someService;
_EntityConverter = entityConverter;
}
// this would be used when injecting via an IOC container, where it would be tedious
// to always specify the implementations for the converters
public SomeController(ISomeService someService)
: this(someService, new EntityConverter())
{
}
public ActionResult Index(SomeViewModel someViewModel)
{
if (!ModelState.IsValid)
return View(someViewModel);
else
{
ServiceInput serviceInput = _EntityConverter.ConvertToServiceInput(someViewModel);
_SomeService.DoSomething(serviceInput);
return View("Success");
}
}
}
In this very simple example, I am using an interface to do conversions between my view models and the entities that are inputs to the service layer.
I'd prefer to use an interface because this conversion can be mocked, rather than if a static method was used. However, I feel like it would be tedious to always have to specify, in the IOC container, what the implementations are for these conversion implementations, since the implementations for these conversion interfaces sit right next to the interfaces.
This may not be the best solution. I'm open to better alternatives.
Don't use multiple constructors. Your classes should have a single definition of what dependencies it needs. That definition lies in the constructor and it should therefore only have 1 public constructor.
I must say I'm not a fan of using mocking frameworks. I found that a good design of my application and my unit tests prevents me from having to use mocking frameworks all together (of course mileage may vary) .
One trick that helps me is allowing null references to be injected into the constructor by not validating the constructor arguments. This is very convenient for unit tests in cases where the class under test does not use the dependency, while in production you would still have the guarantee that null is not injected, since IOC containers will never inject null into a constructor (or at least none of the containers that I know).
Seems like a code-smell that you need an explicit constructor for testing. What if the testing ctor works but the production one doesn't? Seems like a door for bugs to creep in. It would be ideal for tests to use the same path as real clients as far as possible.
What is different between the two ?
Also if you're using some sort of attribute based DI (e.g. like MEF), I'd not be too worried about decoupling. Having an extra attribute (and the corresponding reference) should not be that big a hit... unless you foresee a change in IOC tech in the future.
Maybe I'm misreading your question, but I'm not sure why you would want to test different constructors. The tests should test what's actually going to be used.
For your tests, you ought to mock your dependencies so that they don't need an IoC container.
Using Moq:
Controller:
public SomeController(IService1 service1, IService2 service2)
{
// Do some cool stuff
}
Test Method:
[Test]
public void Some_Action_In_SomeController_Should_Do_Something()
{
var service1Mock = new Mock<IService1>();
var service2Mock = new Mock<IService2>();
var controller = new SomeController(service1Mock.Object, service2Mock.Object);
controller.Action();
// Assert stuff
}
It's all to do with your service locator, you need to configure it where you register your types.
Here is an example of using the default parameterless constructor when using Unity.
Note that by default the service locator will use the most specific constructor (the one with the most parameters)
ServiceLocator.Current.RegisterType<ICache, HttpContextCache>(new InjectionConstructor()); //use default constructor
So why did I need this? It is true I could have made a protected virtual method to resolve HttpContextBase and use extract and override in the test, or otherwise yet another interface with a method that creates the HttpContextBase that can be injected into this class.... or I could just tell unity to use the default constructor.
private readonly HttpContextBase _httpContextBase;
public HttpContextCache()
{
_httpContextBase = new HttpContextWrapper(HttpContext.Current);
}
public HttpContextCache(HttpContextBase httpContextBase)
{
_httpContextBase = httpContextBase;
}
This was a rare case and pretty much all other classes in the project have only one constructor
Pretty new to dependency injection and I'm trying to figure out if this is an anti pattern.
Let's say I have 3 assemblies:
Foo.Shared - this has all the interfaces
Foo.Users - references Foo.Shared
Foo.Payment - references Foo.Shared
Foo.Users needs an object that is built within Foo.Payment, and Foo.Payment also needs stuff from Foo.Users. This creates some sort of circular dependency.
I have defined an interface in Foo.Shared that proxies the Dependency Injection framework I'm using (in this case NInject).
public interface IDependencyResolver
{
T Get<T>();
}
In the container application, I have an implementation of this interface:
public class DependencyResolver:IDependencyResolver
{
private readonly IKernel _kernel;
public DependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public T Get<T>()
{
return _kernel.Get<T>();
}
}
The configuration looks like this:
public class MyModule:StandardModule
{
public override void Load()
{
Bind<IDependencyResolver>().To<DependencyResolver>().WithArgument("kernel", Kernel);
Bind<Foo.Shared.ISomeType>().To<Foo.Payment.SomeType>(); // <- binding to different assembly
...
}
}
This allows me to instantiate a new object of Foo.Payment.SomeType from inside Foo.Users without needing a direct reference:
public class UserAccounts:IUserAccounts
{
private ISomeType _someType;
public UserAccounts(IDependencyResolver dependencyResolver)
{
_someType = dependencyResolver.Get<ISomeType>(); // <- this essentially creates a new instance of Foo.Payment.SomeType
}
}
This makes it unclear what the exact dependencies of the UserAccounts class are in this instance, which makes me think it's not a good practice.
How else can I accomplish this?
Any thoughts?
Althought somewhat controversial: yes, this is an anti-pattern. It's known as a Service Locator and while some consider it a proper design pattern, I consider it an anti-pattern.
This issue is that usage of e.g. your UserAccounts class becomes implicit instead of explicit. While the constructor states that it needs an IDependencyResolver, it doesn't state what should go in it. If you pass it an IDependencyResolver that can't resolve ISomeType, it's going to throw.
What's worse is that at later iterations, you may be tempted to resolve some other type from within UserAccounts. It's going to compile just fine, but is likely to throw at run-time if/when the type can't be resolved.
Don't go that route.
From the information given, it's impossible to tell you exactly how you should solve your particular problem with circular dependencies, but I'd suggest that you rethink your design. In many cases, circular references are a symptom of Leaky Abstractions, so perhaps if you remodel your API a bit, it will go away - it's often surprising how small changes are required.
In general, the solution to any problem is adding another layer of indirection. If you truly need to have objects from both libraries collaborating tightly, you can typically introduce an intermediate broker.
In many cases, a Publish/subscribe model works well.
The Mediator pattern may provide an alternative if communication must go both ways.
You can also introduce an Abstract Factory to retrieve the instance you need as you need it, instead of requiring it to be wired up immediately.
I agree with ForeverDebugging - it would be good to eliminate the circular dependency. See if you can separate the classes like this:
Foo.Payment.dll: Classes that deal only with payment, not with users
Foo.Users.dll: Classes that deal only with users, not with payment
Foo.UserPayment.dll: Classes that deal with both payment and users
Then you have one assembly that references two others, but no circle of dependencies.
If you do have a circular dependency between assemblies, it doesn't necessarily mean you have a circular dependency between classes. For example, suppose you have these dependencies:
Foo.Users.UserAccounts depends on Foo.Shared.IPaymentHistory, which is implemented by Foo.Payment.PaymentHistory.
A different payment class, Foo.Payment.PaymentGateway, depends on Foo.Shared.IUserAccounts. IUserAccounts is implemented by Foo.Users.UserAccounts.
Assume there are no other dependencies.
Here there is a circle of assemblies that will depend on each other at runtime in your application (though they don't depend on each other at compile time, since they go through the shared DLL). But there is no circle of classes that depend on each other, at compile time or at runtime.
In this case, you should still be able to use your IoC container normally, without adding an extra level of indirection. In your MyModule, just bind each interface to the appropriate concrete type. Make each class accept its dependencies as arguments to the constructor. When your top-level application code needs an instance of a class, let it ask the IoC container for the class. Let the IoC container worry about finding everything that class depends on.
If you do end up with a circular dependency between classes, you probably need to use property injection (aka setter injection) on one of the classes, instead of constructor injection. I don't use Ninject, but it does support property injection - here is the documentation.
Normally IoC containers use constructor injection - they pass dependencies in to the constructor of the class that depends on them. But this doesn't work when there is a circular dependency. If classes A and B depend on each other, you'd need to pass an instance of class A in to the constructor of class B. But in order to create an A, you need to pass an instance of class B into its constructor. It's a chicken-and-egg problem.
With property injection, you tell your IoC container to first call the constructor, and then set a property on the constructed object. Normally this is used for optional dependencies, such as loggers. But you could also use it to break a circular dependency between two classes that require each other.
This isn't pretty though, and I'd definitely recommend refactoring your classes to eliminate circular dependencies.
That does seem a little odd to me. Is it possible to separate the logic which needs both references out into a third assembly to break the dependencies and avoid the risk?