How do i abstract my DI tool from UI/Service layer - c#

this question is a follow-up of this question i posted last weekend.
As of now, i have something like this in my service layer which talks with UI in MVC application.
IDepartmentService deptService = kernel.Get<IDepartmentService>();
IList<Department> deptList = deptService.GetAllDepartments();
Everything is fine and DI is working as expected. However, for some reason if i decide to use Structuremap then my entire service layer needs to be changed. How do i abstract it out so that a change in DI tool wont affect my service layer or has minimum impact.

However, for some reason if i decide to use Structuremap then my
entire service layer needs to be changed.
That's not true. As shown in the previous thread the Service Layer doesn't know anything about the DI framework.
You should have a layer called composition root. This is the only layer which is aware of the DI framework and all the underlying layers. This is where you are doing the composition. So if you change the DI framework, the only place you need to make changes is in the composition root.
So you should absolutely get rid of kernel.Get<> calls from your service. Right now you are using Service Locator and not Dependency Injection. Service Locator is an anti-pattern. Your service layer should look like this:
public class MyService
{
private readonly ISomeDependency dependency;
public MyService(ISomeDependency dependency)
{
this.dependency = dependency;
}
public void SomeMethod()
{
// do something with the dependency here
}
}
instead of:
public class MyService
{
private readonly ISomeDependency dependency;
public MyService()
{
this.dependency = kernel.Get<ISomeDependency>();
}
public void SomeMethod()
{
// do something with the dependency here
}
}

Related

MVVM Light SimpleIoc

I'm using WPF with MVVM Light in my project. I have some small question about SimpleIoC containter and DI. Which is the better way to use it or tell me if I don't need to use DI there.
There is my VM constructor:
public MainViewModel(IDialogService dialogService, IChannelObserverService channelObserverService, IInternalBroadcastService internalBroadcastService,
IUserDataAccessService userDataAccessService, IUserService userService)
And SimpleIoC register:
SimpleIoc.Default.Register<MainViewModel>(() => {
return new MainViewModel(SimpleIoc.Default.GetInstance<IDialogService>(),
SimpleIoc.Default.GetInstance<IChannelObserverService>(),
SimpleIoc.Default.GetInstance<IInternalBroadcastService>(),
SimpleIoc.Default.GetInstance<IUserDataAccessService>(),
SimpleIoc.Default.GetInstance<IUserService>()); });
Please tell me, do I need to use DI there?
First I had using all services like this:
public MainViewModel(){...}
User user = SimpleIoc.Default.GetInstance<IUserService>().GetCurrentLoggedUser();
or this:
private IDialogService dialogService;
public MainViewModel()
{
dialogService = = SimpleIoc.Default.GetInstance<IUserService>();
}
private void MyMethod()
{
dialogService.ShowQuestionDialog(abc,abc,abc);
}
So I didn't use DI when I was creating my View-Models.
I'd recommend you to use the DI as it enables the development of loosely coupled code. Through DI, you can decrease tight coupling between software components. Also, it makes unit testing convenient.
I would suggest to have constructor like this (as you have mentioned in your post)
public MainViewModel(IDialogService dialogService, IChannelObserverService channelObserverService, IInternalBroadcastService internalBroadcastService,
IUserDataAccessService userDataAccessService, IUserService userService)
But registration can be simplified as
SimpleIoc.Default.Register<IDialogService, DialogService>();
//// Other service registrations.
SimpleIoc.Default.Register<MainViewModel>(); // without injecting the other dependent types.
With this DI will take to inject the right dependencies while creating an instance of MainViewModel.
So with this above approach, you don't need to Resolve the instance inside your code as it is already inject in constructor, so service code can be simplified as
private void MyMethod()
{
dialogService.ShowQuestionDialog(abc,abc,abc);
}

DbContext Lifetime with Depedency Injection

I'm confused about the proper way to manage my DbContext lifetime using dependency injection in my WinForms application. Right now, I have code that looks like the following
static class Program
{
// This is the main window's controller, which stores all the
// dependencies that are resolved in the composition root and handles
// passing those dependencies to other objects
private static IMainController mainController;
private static void ComposeDependencies
{
UnityContainer container = new UnityContainer();
container.RegisterType<IMyContext, MyContext>();
container.RegisterType<IOrderRepository, OrderRepository>();
container.RegisterType<IOrderService, OrderService>();
mainController = new MainController(
container.Resolve<IOrderService>());
}
}
public class OrderRepository : IOrderRepository
{
private readonly IMyContext context;
public OrderRepository(IMyContext context)
{
this.context = context;
}
}
public class OrderService : IOrderService
{
private readonly IOrderRepository repository;
public OrderService(IOrderRepository repository)
{
this.repository = repository;
}
}
public class MainController
{
private readonly IOrderService orderService;
public MainController(IOrderService orderService)
{
this.orderService = orderService;
}
public void DoSomethingWithAnOrder()
{
FirstTypeOfController controller = new FirstTypeOfController(this.orderService);
// Show window, assign controller, etc.
}
public void DoSomethingElseWithAnOrder()
{
SecondTypeOfController controller = new SecondTypeOfController(this.orderService);
// Show window, assign controller, etc.
}
}
The problem I'm having is that this pattern results in all of my repositories getting created when my program starts, so the MyContext instances stay around through the whole program. So when the database gets updated outside of my program, my program doesn't see the new data because MyContext is using references to the data that it already has loaded.
If this were a web application, then I'd have new dependencies made with every request, but since this is WinForms, I don't understand how to get around this problem while keeping a single composition root and without passing my Unity container all around my program (or having a static reference to it) so that each controller can resolve its own per instance dependencies.
What's the standard solution to this problem, and is there something that I'm doing incorrectly with how/where I'm composing my dependencies or using my DbContext?
I know that MVC is meant more for web applications and something like MVVM or MVP is perhaps more suited to non-web, but those would both have this same problem with a single composition root that only gets called once.
It depends on how you configured your dependency injection, if its Singleton or one instance per scope. I know that on Ninject's DI framework you can specify by using:
//Thread Scope (New instance on each injection)
kernel.Bind<IInterface>.To<ConcreteClass>().InThreadScope();
//Singleton Scope (One instance per application)
kernel.Bind<IInterface>.To<ConcreteClass>().InSingletonScope()
I dont see anything wrong with your implementation, it looks correct. That is right, you are initializing your repositories when your program starts, and that is good, and you keep your contexts for the entire application lifespan. With repositories, you call a method that performs some action against database; in case of fetching data, you always will get the latest data, no matter what, if implemented correctly, unless you would retrieve it on application load and store it somewhere for future access (like global variables, settings as an example).

Correct use of IOC in a multi-threaded application (Decorator or Interceptor?)

I am working on project with a very similar approach like the one in this post. I am using Unity as DI-Framework and I am very new to that.
There is a JobController which should start an injected service n times in a new Task. The code looks pretty much the same as in Chads initial post.
public class Controller
{
IService _service;
public Controller(IService service)
{
this._service = service;
}
public Action DoSomethingManyTimes()
{
for(int i =0; i < numberOfTimes; i++)
{
Task.Factory.StartNew(() =>
{
_service.DoSomething();
});
}
}
}
As my concrete services aren't thread safe, I followed Marks approach and implemented a decorator which needs a factory for each concrete service like the example in Marks answer. My classes looks like that:
public ThreadSafeService1 : IService
{
private readonly IServiceFactory factory;
public ThreadSafeService1(IServiceFactory factory)
{
this.factory = factory;
}
public void DoSomething()
{
this.factory.Create().DoSomething();
}
}
internal class Service1Factory : IServiceFactory
{
public IService Create()
{
return new Service1();
}
}
I have several problems with that:
The code isn't DRY. I don't want to code a ThreadSafeService-Decorator for each of my services. And also I don't want to have a new ServiceFactory for each of my services.
The implementation of my ServiceFactories have to know how to create the concrete services, but as these services are stored as internal classes in another assembly and also have other dependencies (to repositories etc.) which have to be injected, I am not sure where to place the factories and how to create the concrete services with all their dependencies by using Unity.
After watching Marks video I tried to solve the first issue by implementing an interceptor for Unity like the following:
internal class ThreadSafeServiceInterceptor : IInterceptionBehavior
{
IServiceFactory serviceFactory;
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
serviceFactory.Create().Start();
return getNext()(input, getNext);
}
...
}
The serviceFactory is injected via constructor. Apart from the fact that I still haven't found a good solution for issue 2, how can I tell Unity which concrete SessionFactory has to be injected to my interceptor? It depends on the service which is started. At the moment in my application I do something like that:
var service = container.Resolve<IService>("Service1");
var controller = container.Resolve<JobController>(new ParameterOverride("service", service));
controller.StartWork();
But of course the service can't be resolved. Unity isn't able to inject the serviceFactory as there are several registrations for IServiceFactory (for each of my services).
In addition to that my interceptor would create a new service instance and start it. After that, when calling getNext()(), the resolved service starts too and do the same things. But as there could be other interceptors I have to call getNext().
All that lets me think that I am not on the right way. As I have learned, the interceptors should handle cross-cutting concerns. But making a service multi-threaded isn't a cross-cutting concern, right?
Perhaps someone can point me into the right direction?
UPDATE
#oleksii:
Yes and no. It is a real world project but I am still drafting the architecture. For that I want to have a small protoype and check it against the requirements. I do have several services which can be consumed via different UIs.
In this case the UI is a console application which processes incoming Jobs. One job has to process several units. To do that each Job consumes a concrete service-implementation but as the services are designed to process just one unit. Of course I can do something like that in my JobController.
foreach(var unit in unitsToProcess)
{
_service.DoSomethingWithUnit(unit);
}
But I want to process several units parallel. This is why I think I need several instances of my concrete service.
I would do things like this
public class Controller
{
Func<IService> _factory;
public Controller(Func<IService> factory)
{
_factory = factory;
}
public Action DoSomethingManyTimes()
{
for(int i =0; i < numberOfTimes; i++)
{
Task.Factory.StartNew(() =>
{
_factory().DoSomething();
});
}
}
}
Any decent DI Container should know how to resolve a Func (I don't use Unity, autofac does that by default). So, you inject a factory for your services then each task will have their own instance of the service.
I'm usually using this approach for singleton repositories where I inject a factory of DbConnection or whatever I need , then each method will work with a different instance and no state is shared.
Update
The service factory can be an abstract one, so you don't have one factory per service, but one for all services. So maybe something like this
Func<string,IService>
And you set up Unity to inject only the factory method (from your service factory class). That factory can encapsulate Unity to create the actual services

Get the container instance for Simple Injector

I am using Simple Injector with a ASP.NET MVC project. I added the SimpleInjector.Integration.Web.Mvc nuget package. This adds SimpleInjectorInitializer class in App_Start folder and initializes the DI. The code looks something like
public static void Initialize()
{
// Did you know the container can diagnose your configuration?
// Go to: https://simpleinjector.org/diagnostics
var container = new Container();
//Container configuration code
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
}
This configures the DI for the MVC controller correctly.
My question is, if I want to get the instance of the container in any of the controller\class to resolve some dependency manually how can I do it.
I have earlier worked on AutoFac and it has a dependency interface IComponentContext which can be injected into any class that needs to do any resolution manually.
Update:
Here is a scenario. My controller uses a service who initialization depends upon the input parameter passed in the controller method and hence the dependency cannot be instantiated during construction time.
I understand that this is somewhat an anti pattern for DI, but it is requirement at few places and hence injecting the DI container is next best thing. Simple Injector samples should use of static variable to share the container which i want to avoid and also it is not possible by the way SimpleInjectorInitializer works.
Except for any code that is part of the startup path of the application, no code should depend directly on the container (or a container abstraction, container facade, etc). This pattern is called Service Locator and Mark Seemann has a good explanation why this is a bad idea.
So components (such as Controllers) should not depend on the container directly, since this hides the used dependencies and makes classes harder to test. Furthermore your code starts to depend on an external framework (making it harder to change) or depending on an abstraction it doesn't need to know about.
My controller uses a service who initialization depends upon the input
parameter passed in the controller method and hence the dependency
cannot be instantiated during construction time
There's a general pattern for this problem: the abstract factory design pattern. The factory pattern allows you to delay the creation of types and allows you to pass in extra runtime parameters for the construction of a certain type. When you do this, your controller doesn't have to depend on Container and it prevents you from having to pass in a constructed container in your unit tests (DI frameworks should in general not be used in your unit test projects).
Do note however that letting your components require runtime data during creation is a code smell. Prevent doing that.
You might think that by doing this we are just moving the problem to the factory implementation. Although we are moving the dependency on the container into the factory implementation, we are in fact solving the problem because the factory implementation will be part of the application's Composition Root, which allows the application code itself oblivious to any DI framework.
So this is how I advice you to structure your code:
// Definition of the factory in the UI or BL layer
public interface ISomeServiceFactory
{
ISomeService Create(int inputParameter);
}
// Controller depending on that factory:
public class MyController : Controller
{
private readonly ISomeServiceFactory factory;
public MyController(ISomeServiceFactory factory)
{
this.factory = factory;
}
public ActionResult Index(int value)
{
// here we use that factory
var service = this.factory.Create(value);
}
}
In your composition root (the start up path) we define the factory implementation and the registration for it:
private class SomeServiceFactory : ISomeServiceFactory
{
private readonly Container container;
// Here we depend on Container, which is fine, since
// we're inside the composition root. The rest of the
// application knows nothing about a DI framework.
public SomeServiceFactory(Container container)
{
this.container = container;
}
public ISomeService Create(int inputParameter)
{
// Do what ever we need to do here. For instance:
if (inputParameter == 0)
return this.container.GetInstance<Service1>();
else
return this.container.GetInstance<Service2>();
}
}
public static void Initialize()
{
var container = new Container();
container.RegisterSingle<ISomeServiceFactory, SomeServiceFactory>();
}
Upon creation, the Container registers itself (using the call RegisterSingle<Container>(this)) so you can always inject the container into any component. That's similar to injecting the IComponentContext when working with Autofac. But the same holds for Autofac, Simple Injector, and any other container: you don't want to inject your container into components that are located outside the composition root (and there hardly ever is a reason for it).

DI with Repository and Services in different DLLs, keeping separation of concerns

I have a layered application with the following projects:
DAL (using EntityFramework with repositories)
DAL.Model (contains the entities, and is referenced by all the others)
Services
UI (in wpf)
The base repository looks like this:
public abstract class RepositoryBase<T> where T : class
{
private readonly MyContext context;
private readonly IDbSet<T> dbSet;
protected RepositoryBase(MyContext dataContext)
{
context = dataContext;
dbSet = context.Set<T>();
}
protected MyContext Context
{
get { return context; }
}
**And a series of virtual methods for Add, Delete, etc.
}
All repositories extend this one, such as:
public class MarketRepository : RepositoryBase<Market>
{
public MarketRepository(MyContext dataContext) : base(dataContext)
{
}
public IEnumerable<Market> GetAllMarkets()
{
return this.Context.Markets.ToList<Market>();
}
}
The services look like this:
public class MarketService
{
IMarketRepository _marketRepository;
public MarketService(IMarketRepository marketRepository)
{
_marketRepository = marketRepository;
}
public IEnumerable<Market> GetAllMarkets()
{
return _marketRepository.GetAllMarkets();
}
}
What I would like to achieve is that the UI layer would only have a reference to the Services layer, the Services layer only with the DAL layer (and all of them to Model, where the entities live) using DI (right now I'm using Unity).
The problem is, in my container in the UI I only want to do this
unity.RegisterType<IMarketService, MarketService>();
and not have to do it as well for the repositories, because then the UI layer would have a dependency on the DAL layer.
I thought about adding a parameterless constructor to the Service classes, like:
public MarketService() : this(new MarketRepository(*What would I put here?)) { }
but then I'm loosing the abstraction that the interface gives, and also I don't know what to do with the MyContext that the repository needs as a parameter; if I pass a new one, then I need to reference the DAL.
Should I change my repositories to create a new MyContext in the constructor, rather than getting it as a parameter?
How can I refactor my architecture to make it work properly and with minimal dependencies?
Well, I belive it is up to the bootstrapper to configure dependencies, in the higher level of the application. As it is usually the UI project, if it needs to reference other assemblies, so be it. If you do not like your UI project managing that, than create a bootstrapper project responsable for getting your app running and separete your UI classes in another one.
Your IoC container should support Dependency Injection using a string from an external configuration file. This way you are not hardcoding the mapping. Structuremap does this quite well, so I am sure other IoCs will.
Adding external dependenices as a parameter when creating an instance is the way to go.
I think you should make yourself more familiar with the different ways to configure Unity, so that the dependencies are resolved.
Could you elaborate why you are creating a repository when using a dependency injection framework?
When configuring DI, you should follow the same pattern - UI bootstrapper initializes Services, Services initialize DAL. (With autofac or ninject you could achiece this using modules. With unity you should emulate modules).
In pseudocode something like
//ui
void UILayer.ConfigureUnity(unity)
{
ServiceLayer.ConfigureUnity(unity)
}
//services
void ServiceLayer.ConfigureUnity(unity)
{
DAL.ConfigureUnity(unity)
unity.RegisterType<IMarketService, MarketService>();
}
//dal
void DAL.ConfigureUnity(unity)
{
unity.RegisterType<IMarketRepository, MarketRespository>();
unity.RegisterType<MyContext, MyContext>(); //not sure exact syntax - just register type for 'new Type()' activator.
}

Categories

Resources