I have a question regarding creating a class diagram where I have used dependency injection.
I have following code example:
public class ReservationController : ApiController
{
private readonly IGetReservationService _getReservationService;
public ReservationController(IGetReservationService getReservationService)
{
_getReservationService = getReservationService;
}
// GET list of all reservations
public List<ReservationViewModel> GetReservations()
{
return _getReservationService.GetReservations();
}
// GET single reservation by id
public List<ReservationViewModel> GetReservation(string reservationNumber)
{
return _getReservationService.GetReservation(reservationNumber);
}
}
Here you see that the controller (ReservationController) getting the IGetReservationService injected in the constructor. When creating the relationship between the controller and the interface, do you then use a dependency or an association?
My guess is that it should be a dependency since we are using dependency injection?
Good day.
Yes, this is a dependency. An association is used if you have object references (e.g. for a property).
Related
Need some help trying to solve a problem resolving an implementation of a service at runtime based on a parameter. In other words use a factory pattern with DI.
We have Autofac wired in to our MVC application. I am trying to figure out how we can use a user session variable (Call it Ordering Type) to be used for the Dependency Resolver to resolve the correct implementation of a service.
An example of what we are trying to do.
The application has two "types" of ordering - real eCommerce type of ordering (add stuff to a shopping cart, checkout etc).
The other is called Forecast ordering. Users create orders - but they do not get fulfilled right away. They go through an approval process and then fulfilled.
The bottom line is the data schema and back end systems the application talks to changes based on the order type.
What I want to do is:
I have IOrderManagerService
public interface IOrderManagerService
{
Order GetOrder(int orderNumber);
int CreateOrder(Order order);
}
Because we have two ordering "types" - I have two implementations of the the IOrderManagerService:
public class ShelfOrderManager : IOrderManagerService
{
public Order GetOrder(int orderMumber)
{
...code
}
public int CreateOrder(Order order)
{
...code
}
}
and
public class ForecastOrderManager: IOrderManagerService
{
public Order GetOrder(int orderMumber)
{
...code
}
public int CreateOrder(Order order)
{
...code
}
}
My First question is - in my MVC application - do I register these implementations as?
builder.RegisterType<ShelfOrderManager>().As<IOrderManagerService>();
builder.RegisterType<ForecastOrderManager>().As<IOrderManagerService>();
What we are planning on doing is sticking the user selected ordering type in a users session. When a user wants to view order status - depending on their selected ordering "type" - I need the resolver to give the controller the correct implementation.
public class OrderStatusController : Controller
{
private readonly IOrderManagerService _orderManagerService;
public OrderStatusController(IOrderManagerService orderManagerService)
{
//This needs to be the correct implementation based on the users "type".
_orderManagerService = orderManagerService;
}
public ActionResult GetOrder(int orderNumber)
{
var model = _orderManagerService.GetOrder(orderNumber);
return View(model);
}
}
I've ready about the the delegate factory and this answer explains the concept well.
The problem is the runtime parameters are being used to construct the service and resolve at runtime. i.e.
var service = resolvedServiceClass.Factory("runtime parameter")
All this would do is give me "service" that used the "runtime parameter" in the constructor.
I've looked at Keyed or Named resolution too.
At first I thought I could combine these two techniques - but the controller has the dependency on the interface - not the concrete implementation. (as it should)
Any ideas on how to get around this would be MUCH appreciated.
As it would turn out we were close. #Andrei is on target with what we did. I'll explain the answer below for the next person that comes across this issue.
To recap the problem - I needed to resolve a specific concrete implementation of an interface using Autofac at run time. This is commonly solved by the Factory Pattern - but we already had DI implemented.
The solution was using both. Using the delegate factory Autofac supports, I created a simple factory class.
I elected to resolve the component context privately
DependencyResolver.Current.GetService<IComponentContext>();
versus having Autofac resolve it predominately so I did not have to include IComponentContext in all of my constructors that that will be using the factory.
The factory will be used to resolve the services that are dependent on run time parameters - which means wherever a
ISomeServiceThatHasMultipleImplementations
is used in a constructor - I am going to replace it with ServiceFactory.Factory factory. I did not want to ALSO include IComponentContext wherever I needed the factory.
enum OrderType
{
Shelf,
Forecast
}
public class ServiceFactory : IServiceFactory
{
private readonly IComponentContext _componentContext;
private readonly OrderType _orderType;
public ServiceFactory(OrderType orderingType)
{
_componentContext = DependencyResolver.Current.GetService<IComponentContext>();
_orderType = orderingType;
}
public delegate ServiceFactory Factory(OrderType orderingType);
public T Resolve<T>()
{
if(!_componentContext.IsRegistered<T>())
return _componentContext.ResolveNamed<T>(_orderType.ToString());
return _componentContext.Resolve<T>();
}
}
With the factory written, we also used the Keyed services.
Using my order context -
public interface IOrderManagerService
{
Order GetOrder(int orderNumber);
int CreateOrder(Order order);
}
public class ShelfOrderManager : IOrderManagerService
{
public Order GetOrder(int orderNumber)
{
...
}
public int CreateOrder(Order order)
{
...
}
}
public class ForecastOrderManager : IOrderManagerService
{
public Order GetOrder(int orderNumber)
{
...
}
public int CreateOrder(Order order)
{
...
}
}
The registration of Keyed services:
//register the shelf implementation
builder.RegisterType<ShelfOrderManager>()
.Keyed(OrderType.Shelf)
.As<IOrderManager>();
//register the forecast implementation
builder.RegisterType<ForecastOrderManager>()
.Keyed(OrderType.Shelf)
.As<IOrderManager>();
Register the factory:
builder.RegisterType<IMS.POS.Services.Factory.ServiceFactory>()
.AsSelf()
.SingleInstance();
Finally using it in the controllers (or any other class for that matter):
public class HomeController : BaseController
{
private readonly IContentManagerService _contentManagerService;
private readonly IViewModelService _viewModelService;
private readonly IApplicationSettingService _applicationSettingService;
private readonly IOrderManagerService _orderManagerService;
private readonly IServiceFactory _factory;
public HomeController(ServiceFactory.Factory factory,
IViewModelService viewModelService,
IContentManagerService contentManagerService,
IApplicationSettingService applicationSettingService)
{
//first assign the factory
//We keep the users Ordering Type in session - if the value is not set - default to Shelf ordering
_factory = factory(UIUserSession?.OrderingMode ?? OrderType.Shelf);
//now that I have a factory to get the implementation I need
_orderManagerService = _factory.Resolve<IOrderManagerService>();
//The rest of these are resolved by Autofac
_contentManagerService = contentManagerService;
_viewModelService = viewModelService;
_applicationSettingService = applicationSettingService;
}
}
I want to work out a bit more handling of the Resolve method - but for the first pass this works. A little bit Factory Pattern (where we need it) but still using Autofac to do most of the work.
I would not rely on Autofac for this. IOC is used to resolve a dependency and provide an implementation for it, what you need is to call a different implementation of the same interface based on a decision flag.
I would use a simple factory basically, like a class with 2 static methods and call whichever implementation you need need to when you know what the decision is. This gives you the run-time resolver you are after. Keep it simple I'd say.
This being said it seems there is another option. Have a look at the "select by context" option, maybe you can redesign your classes to take advantage of this: http://docs.autofac.org/en/latest/faq/select-by-context.html
We have an MVC3 controller in which there is some 'common' work that we rolled into the controller constructor. Some of that common work is done by a losely coupled class (say ourService) that's dynamically resolved through Unity (for IoC / Dependency injection). ourService is null (i.e. not resolved) in the Controller's constructor BUT it's properly resolved in the usual Controller methods. The simple demo code below shows the issue:
public class Testing123Controller : BaseController
{
[Dependency]
public IOurService ourService { get; set; }
public Testing123Controller()
{
ourService.SomeWork(1); // ourService=null here !!
...
}
public ActionResult Index()
{
ourService.SomeWork(1); // resolved properly here here !!
...
}
...
}
Question:
Why is there this different in Unity resolution behavior? I would expect consistent behavior.
How can I fix it so Unity resolves this even in the controller's contructor?
The way we've setup Unity 2.0 is :
Global.asax
Application_Start()
{
...
Container = new UnityContainer();
UnityBootstrapper.ConfigureContainer(Container);
DependencyResolver.SetResolver(new UnityDependencyResolver(Container));
...
}
public static void ConfigureContainer(UnityContainer container)
{
...
container.RegisterType<IOurService, OurService>();
...
}
IOurService.cs
public interface IOurService
{
bool SomeWork(int anInt);
}
OurService.cs
public class OurService: IOurService
{
public bool SomeWork(int anInt)
{
return ++anInt; //Whew! Time for a break ...
}
}
As a basic principle of classes, before an instance property can be set, the instance has to be instantiated.
Unity needs to set the dependency property, but it can't do so until the instance has been fully instantiated - i.e. the constructor must have completed executing.
If you are referencing the dependency property in the constructor, then this is too early - there is no way for Unity to have set it yet - and therefore it will be unset (i.e. null).
If you need to use the dependency in the constructor, then you must use constructor injection. Although in general, using constructor injection is usually the better method anyway:
public class Testing123Controller : BaseController
{
public IOurService ourService { get; set; }
public Testing123Controller(IOurService ourService)
{
this.ourService = ourService;
this.ourService.SomeWork(1); // ourService no longer null here
...
}
public ActionResult Index()
{
ourService.SomeWork(1); // also resolved properly here
...
}
...
}
Note: In the example I left ourService as a publicly gettable & settable property in case other parts of your code need to access it. If on the other hand it is only accessed within the class (and had only been made public for Unity purposes), then with the introduction of constructor injection, it would be best to make it a private readonly field.
You are using property injection (by using the Dependency attribute) rather than constructor injection so the dependency is not resolved until after the controller is instantiated. If you want to have access to the dependency is the constructor, just add it to the ctor:
private readonly IOurService _ourService { get; set; }
public Testing123Controller(IOurService ourService)
{
_ourService = ourService;
_ourService.SomeWork(1); // ourService=null here !!
...
}
I'm afraid that for Unity to work on the constructor, the instance itself must be resolved using Unity. The fact that the Service property is null in the constructor supports this idea. If you call the Controller yourself (NOT with Unity), Unity has no time to resolve the property.
Preliminaries
I'm using Ninject.MVC3 2.2.2.0 Nuget Package for injecting into my controller an implementation of a IDomain Interface that separates my Business Logic (BL) using an Factory approach.
I'm registering my Ninject Modules in the preconfigured NinjectMVC3.cs using:
private static void RegisterServices(IKernel kernel)
{
var modules = new INinjectModule[]
{
new DomainBLModule(),
new ADOModule()
};
kernel.Load(modules);
}
I'm trying to avoid the fatal curse of the diabolic Service Locator anti-pattern.
The Domain Class uses a DBContext that i'm trying to inject an interface implementation too, via an IDBContext, with the following scenario:
IDomainBLFactory:
public interface IDomainBLFactory
{
DomainBL CreateNew();
}
DomainBLFactory:
public class DomainBLFactory : IDomainBLFactory
{
public DomainBL CreateNew()
{
return new DomainBL();
}
}
In the controller's namespace:
public class DomainBLModule : NinjectModule
{
public override void Load()
{
Bind<IDomainBLFactory>().To<DomainBLFactory>().InRequestScope();
}
}
At this point i can inject the IDomainBLFactory implementation into my controller using Ninject Constructor Injection without any problem:
public class MyController : Controller
{
private readonly IDomainBLFactory DomainBLFactory;
// Default Injected Constructor
public MyController(IDomainBLFactory DomainBLFactory)
{
this.DomainBLFactory = DomainBLFactory;
}
... (use the Domain for performing tasks/commands with the Database Context)
}
Now my central problem.
In the DomainBL implementation, i will inject the dependency to a particular DBContext, in this case ADO DBContext from Entity Framework, again, using a IDBContextFactory:
IDbDataContextFactory
public interface IDbDataContextFactory
{
myADOEntities CreateNew();
}
DbDataContextFactory
public class DbDataContextFactory : IDbDataContextFactory
{
public myADOEntities CreateNew()
{
return new myADOEntities ();
}
}
ADOModule
public class ADOModule : NinjectModule
{
public override void Load()
{
Bind<IDbDataContextFactory>().To<DbDataContextFactory>().InRequestScope();
}
}
Now in the DomainBL implementation I faced the problem of injecting the necessary interface for the DBContext Object Factory:
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
**** OPS, i tried to understand about 10+ Stackoverflow articles ***
...
}
What have I tried?
To Use the constructor Injection. But I don't know what to inject in the call for the Factory CreateNew() in the IDBContextFactory. For clear:
public class DomainBLFactory: IDomainBLFactory
{
// Here the constructor requires one argument for passing the factory impl.
public DomainBL CreateNew()
{
return new DomainBL(?????) // I need a IDBContextFactory impl to resolve.
//It's not like in the MVC Controller where injection takes place internally
//for the controller constructor. I'm outside a controller
}
}
In this Useful Post, our unique true friend Remo Gloor describes in a comment a possible solution for me, citing: "Create an interface that has a CreateSomething method that takes everything you need to create the instance and have it return the instance. Then in your configuration you implement this interface and add an IResolutionRoot to its constructor and use this instace to Get the required object."
Questions: How do I implement this in a proper way using Ninject.MVC3 and my modest Domain Class approach? How do I Resolve the IResolutionRoot without be punished for relaying in the Service Locator anti-pattern?
To Use the property injection for an IDBContexFactory. In the course of learning and reading all the contradictory points of view plus the theoretical explanations about it, I can deduce it's not a proper way of doing the injection for my DBContexFactory class code. Nevermind. It doesn't work anyway.
public class DomainBL
{
[Inject]
public IDbDataContextFactory contextFactory
{
get;
set;
}
//Doesn't works, contextFactory is null with or without parameterless constructor
.... (methods that uses contextFactory.CreateNew()....
}
Question: What am I missing? Even if this approach is wrong the property is not injecting.
Be cursed. Use a DependencyResolver and live with the stigmata. This works and I will remain in this approach until a proper solution appears for me. And this is really frustrating because the lack of knowledge in my last 10 days effort trying to understand and do things right.
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
this.contextFactory = DependencyResolver.Current.GetService<IDbDataContextFactory>();
//So sweet, it works.. but i'm a sinner.
}
Question: Is there a big mistake in my understanding of the Factory Approach for the injection of interfaced implementations and using a Domain Driven Approach for taking apart the Business Logic? In the case I'm wrong, what stack of patterns should I implement with confidence?
I saw before a really big quantity of articles and blogs that does not ask this important question in a open a clear way.
Remo Gloor introduces the Ninject.Extensions.Factory for the Ninject 3.0.0 RC in www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction.
Question: Will this extension work coupled with Ninject.MVC3 for general porpouse?. In such case it should be my hope for the near future.
Thank you all in advance for your guidance and remember we appreciate your kind help. I think a lot of people will find this scenario useful too.
I don't really get the purpose of your factories. Normally, you have exactly one ObjectContext instance for one request. This means you don't need the factory and can simply bind myADOEntities in Request scope and inject it into your DomainBL without adding the factories:
Bind<myADOEntities>().ToSelf().InRequestScope();
Bind<DomainBL>().ToSelf().InRequestScope();
And Yes the factory and mvc extrensions work together.
Here's an implementation of a generic IFactory to solve the problem without resorting to the ServiceLocator anti-pattern.
First you define a nice generic factory interface
public interface IFactory<T>
{
T CreateNew();
}
And define the implementation which uses ninject kernel to create the objects requested
class NinjectFactory<T> : IFactory<T>
{
private IKernel Kernel;
public NinjectFactory( IKernel Kernel )
{
this.Kernel = Kernel;
}
public T CreateNew()
{
return Kernel.Get<T>();
}
}
Binding to your factory using the following
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<myADOEntities>().ToSelf();
kernel.Bind<DomainBL>().ToSelf();
kernel.Bind(typeof(IFactory<>)).To(typeof(NinjectFactory<>));
}
You can now do the following in your controller.
public class MyController : Controller
{
private readonly IFactory<DomainBL> DomainBLFactory;
public MyController( IFactory<DomainBL> DomainBLFactory )
{
this.DomainBLFactory = DomainBLFactory;
}
// ... (use the Domain for performing tasks/commands with the Database Context)
}
And in your DomainBL
public class DomainBL
{
IFactory<myADOEntities> EntitiesFactory;
public DomainBL( IFactory<myADOEntities> EntitiesFactory )
{
this.EntitiesFactory = EntitiesFactory;
}
// ... (use the Entities factory whenever you need to create a Domain Context)
}
We are using EF4 and creating test cases for DAL layer (DAL layer is having linq query). We are using TypeMock as mocking framework. For testing, we are creating Fakecontext of ObjectContext and mocking CreateObjectSet method as follows:
Isolate.WhenCalled(() => fakeContext.Context.CreateObjectSet<User>)).WillReturnCollectionValuesOf(fakeUsers.AsQueryable());
The above is working fine. The issue is when we are trying to include related tables using 'Include'. We have extended the include method as follows:
public static IQueryable<T> Include<T>(this IQueryable<T> source, Expression<Func<T>> property)
{
var objectQuery = source as ObjectQuery<T>;
if (objectQuery != null)
{
var propertyPath = GetPropertyPath(property);
return objectQuery.Include(propertyPath);
}
return source;
}
So what happen is, in the above Include method the source type should be ObjectQuery<T>. But as we have mocked CreateObjectSet, source type in Include method is of Collection.Generic.List type. Kindly let us know how should we mock in the above case. Your timely help will be highly appreciable. Thanks
Object Services can be difficult to use when writing unit test. Unfortunately, there is not a good interface to mock for ObjectQuery<T> as you have found out. To handle this scenario I have created a wrapper class following the Repository pattern to encapsulate my ObjectContext and created a wrapper class to encapsulate ObjectQuery<T>:
public interface IMyObjectQuery<T> : IOrderedQueryable<T>
{
IMyObjectQuery<T> Include(string path);
}
public class MyObjectQuery<T> : IMyObjectQuery<T>
{
private ObjectQuery<T> _query;
public MyObjectQuery(ObjectQuery<T> query)
{
_query = query;
}
IMyObjectQuery<T> Include(string path)
{
//There is probably a better way to do this
//but you get the idea
return new MyObjectQuery(_query.Include(path));
}
//Implement IQueryable, IEnumerable...
}
And then it is a matter of implementing a Repository wrapper for your ObjectContext. Here is a link to get you started.
Add something like this:
public class MyRepository : IMyRespository
{
...
public IMyObjectQuery<T> CreateQuery<T>()
{
return new MyObjectQuery(_context.CreateQuery<T>());
}
...
}
This is probably not the simple solution that you were looking for, as it is not a trivial task. I think you will find that if you don't you will continue to encounter difficulty writing tests.
I have a structuremap configuration that has me scratching my head. I have a concrete class that requires a interfaced ui element which requires an interfaced validation class. I want the outer concrete class to get the default ui element, but get a concrete-class-specific validation object. Something like this:
class MyView
{
IPrompt prompt
}
class GenericPrompt : IPrompt
{
IValidator validator
}
class MyValidator : IValidator
{
bool Validate() {}
}
How can I configure structuremap with the Registry DSL to only use MyValidator when creating dependencies for MyView. (And assumedly using BobsValidator when creating dependencies for BobsView)
Are you getting MyView (and BobsView) from the container? Can we assume that they will all take an instance of IPrompt?
One approach would be to register all of your validators with a name that matches the names of your view. You could implement your own type scanner that just removes the Validator suffix:
public class ValidatorScanner : ITypeScanner
{
public void Process(Type type, PluginGraph graph)
{
if (!typeof (IValidator).IsAssignableFrom(type)) return;
var validatorName = type.Name.Replace("Validator", "");
graph.AddType(typeof(IValidator), type, validatorName);
}
}
Now, if you assume an IPrompt will always be requested by a View that follows that naming convention, your registry could look like:
public class ValidatorRegistry : Registry
{
public ValidatorRegistry()
{
Scan(scan =>
{
scan.TheCallingAssembly();
scan.With<ValidatorScanner>();
});
ForRequestedType<IPrompt>().TheDefault.Is.ConstructedBy(ctx =>
{
var viewName = ctx.Root.RequestedType.Name.Replace("View", "");
ctx.RegisterDefault(typeof(IValidator), ctx.GetInstance<IValidator>(viewName));
return ctx.GetInstance<GenericPrompt>();
});
}
}
To retrieve your view with the appropriate validator, you would have to request the concrete type:
var view = container.GetInstance<MyView>();
Note that this will only work if you are retrieving your view with a direct call to the container (service location), since it depends on the "Root.RequestedType". Depending on how you plan to get your views, you might be able to walk up the BuildStack looking for a View (instead of assuming it is always Root).