Dependency on a service layer with Ninject and MVC - asp.net-mvc

I've got a problem with a bog standard three tier project using MVC that I'm trying to use Ninject with. I've got a MemberRepository:
public class MemberRepository : IMemberRepository{
public bool Save(Member member){
//saves member
}
}
I then have my Service Layer:
public class MemberService : IMemberService{
public bool Register(string email){
//Do Stuff & Populate Member Object
_repo.Save(member);
}
}
Given I'll be using Ninject what is the best way of me setting up my AccountController. Should I pass in the MemberService to the constructor like so:
public class AccountController : Controller
{
IMemberService _memberService;
public AccountController(IMemberService memberService)
{
_memberService = memberService;
}
}
Or pass in the repository:
public class AccountController : Controller
{
IMemberService _memberService;
public AccountController(IMemberRepository memberRepo)
{
_memberService = new MemberService(memberRepo);
}
}
Or Both?
I originally had just a repository (no service layer) but I've had to implement a service layer and I'm not sure how I'd handle the 'dependency' when registering the kernal in my NinjectWebCommon.cs file. Which was originally just this:
kernel.Bind<IMemberRepository>().To<SqlMemberRepository>();
But now I'm wondering if I need to register the IMemberService and have the repo as some kind of parameter.
:s Feeling kind of lost. Hope I'm making sense and someone can help out.

I've never used Ninject, I've been using Unity, but the same principles exist so hopefully this might help.
The service layer is the thing that is exposed to the controller - the controller needs to know nothing about the underlying repository. The flow is as follows, and each layer doesn't know about the layers above it:
Controller -> Service > Repository
So I would go with option 1, and then inject the repository into the constructor of the service.
public class MemberService : IMemberService {
private readonly IMemberRepository _repo;
[Inject]
public MemberService (IMemberRepository repo){
this._repo = repo;
}
public bool Register(string email){
//Do Stuff & Populate Member Object
_repo.Save(member);
}
}
and
public class AccountController : Controller
{
private readonly IMemberService _memberService;
[Inject]
public AccountController(IMemberService memberService)
{
_memberService = memberService;
}
}
That example obviously uses constructor injection but you can use property/field injection if you want instead. When you register your dependencies, you'll have to register both:
kernel.Bind<IMemberRepository>().To<SqlMemberRepository>();
kernel.Bind<IMemberService>().To<MemberService>();

Related

Configure Unity container per-request in OWIN middleware

I'm wanting to configure registrations in a Unity container being used by ASP.NET Web API 2 based on properties of a HTTP request. For example, a request to /api/database1/values should result in a Unity container configuration with an IDbContext configured for database1, while a request to /api/database4/values will get an IDbContext configured for database4.
I've gotten so far as using UnityHierarchicalDependencyResolver as the dependency resolver, so types registered with HierarchicalLifetimeManager last only for the lifetime of the request. This works well for getting types resolved per request. But how to get them registered per request using OWIN middleware is beyond me.
In my middleware, a call to System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUnityContainer)) gets an instance of IUnityContainer, but it's the same container for all requests, including any registrations from previous requests.
By encapsulating UnityHierarchicalDependencyResolver with my own implementation of IDependencyResolver I can see that IDependencyResolver.BeginScope isn't called until much later in the process. So the problem would seem to be that the child container isn't created until Web API wakes up, long after my middleware calls Next(..).
Is there a way I can get the scope of my dependency resolver to start sooner? Is there some other strategy that I'm missing. In case it makes any difference, I'm hosting in IIS, but favouring the OWIN middleware approach.
Update
This isn't an answer, and it's too big for a comment, but after struggling to solve this with Unity I decided to switch to Autofac and it all just fell into place.
The Autofac OWIN packages (Autofac.Mvc5.Owin, Autofac.Owin, Autofac.WebApi2.Owin) make it dead easy to use Autofac within the OWIN pipeline and ensure appropriate lifetime management in ASP.NET MVC and Web API. This was the missing link.
I couldn't find a way to reconfigure the container per-request, but it did at least make it possible to configure a factory per-request (so yes, #Haukinger and #alltej, you were right to push in that direction.
So I register a factory like:
builder.RegisterType<DataDependencyFactory>().InstancePerRequest();
And register the create method of that factory like:
builder
.Register(c => c.Resolve<DataDependencyFactory>().CreateDataDependency())
.As<IDataDependency>()
.InstancePerRequest();
Registering the factory this way is particularly useful, because downstream dependents don't need to be aware of the factory. I like this because my dependents don't need a factory, they need an instance. The container bends to the needs of my dependents, not the other way around :)
Then, in a piece of OWIN middleware, I resolve the factory, and set a property on it according to the properties of the request. Subsequent resolution of IDataDependency in an MVC or Web API controller, or anything else later in the OWIN pipeline, will get an instance configured according to the property on the factory.
Based on your api URL ("/api/database4/values"), I suggest that you create a filter attribute(e.g. DbIdFilter) so that you can reuse the filter attribute to other controller methods that follow similar url path/segment like this below:
[HttpGet]
[DbIdFilter]
[Route("{databaseId}/values")]
public IHttpActionResult GetValues()
{
return Ok();
}
[HttpGet]
[DbIdFilter]
[Route("{databaseId}/products")]
public IHttpActionResult GetProducts()
{
return Ok();
}
First, create the filter attribute:
public class DbIdFilterAttribute : ActionFilterAttribute
{
private readonly string _routeDataId;
private const string defaultRouteName = "databaseId";
public DbIdFilterAttribute():this(defaultRouteName)
{}
public DbIdFilterAttribute(string routeDataId)
{
_routeDataId = routeDataId;
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
var routeData = actionContext.Request.GetRouteData();
var dbId = routeData.Values[_routeDataId] as string;
//here we create the db instance at the filter level.
DbInstanceFactory.RegisterDbInstance(dbId);
}
}
Next, create an instance factory that will register/resolve the db instance during runtime:
public class DbInstanceFactory : IDbInstanceFactory
{
public static IDbInstance RegisterDbInstance(string databaseId)
{
var factory = UnityConfig.GetConfiguredContainer().Resolve<IDbInstanceFactory>();
return factory.CreateInstance(databaseId);
}
public IDbInstance CreateInstance(string databaseId)
{
var container = UnityConfig.GetConfiguredContainer();
//container.RegisterType<IDbInstance, DbInstance>();
container.RegisterType<IDbInstance, DbInstance>(new InjectionConstructor(databaseId));
var dbInstance = container.Resolve<IDbInstance>();
return dbInstance;
}
public IDbInstance GetInstance()
{
var container = UnityConfig.GetConfiguredContainer();
var dbInstance = container.Resolve<IDbInstance>();
return dbInstance;
}
}
public interface IDbInstanceFactory
{
IDbInstance CreateInstance(string databaseId);
IDbInstance GetInstance();
}
Register this factory class in UnityConfig.cs (or wherever you currently register the types):
container.RegisterType<IDbInstanceFactory, DbInstanceFactory>
(new ContainerControlledLifetimeManager());
It's registered ContainerControlledLifetimeManager since this factory does not have to be a per request.
So just a basic DbInstance class below(for clarity) that takes a parameter in the constructor (this parameter can be your connection string or a named connection):
public class DbInstance : IDbInstance
{
public string DbId { get; }
public DbInstance(string databaseId)
{
DbId = databaseId;
}
}
public interface IDbInstance
{
string DbId { get; }
}
In controller class, you can use it like this:
....
private IDbInstanceFactory _dbFactory;
public MyController(IDbInstanceFactory dbFactory)
{
_dbFactory = dbFactory;
}
// Alternate, if you want to use property injection instead of constructor injection
//[Dependency]
//public IDbInstanceFactory DbFactory { get; set; }
[HttpGet]
[DbIdFilter]
[Route("{databaseId}/test")]
public IHttpActionResult Test()
{
var db = _dbFactory.GetInstance();
return Ok(db.DbId);
}
...

Autofac register generic with multiple paramters?

Here are the classes and interfaces I'm dealing with.
public interface IAccountService
{
//omitted for brevity...
}
public abstract class UserClientBase<T> : ClientBase<T> where T : class
{
protected UserClientBase(Binding binding, EndpointAddress remoteAddress, string userName, string password)
: base(binding, remoteAddress)
{
if (ClientCredentials == null) return;
ClientCredentials.UserName.UserName = userName;
ClientCredentials.UserName.Password = password;
}
}
public class AccountProxy : UserClientBase<IAccountService>, IAccountService
{
private static readonly WSHttpBinding Binding = WcfHelpers.ConfigureWsHttpBinding();
private static readonly EndpointAddress EndpointAddress =
new EndpointAddress(#"https://server.project.local/Project/Account/AccountService.svc");
public AccountProxy(string userName, string password)
: base(Binding, EndpointAddress, userName, password)
{
}
//omitted for brevity
}
public interface ISafeClient<out TService> : IDisposable where TService : class
{
//omitted for brevity...
}
public class SafeClient<TClient, TService> : ISafeClient<TService>
where TClient : UserClientBase<TService>, TService
where TService : class
{
//omitted for brevity...
}
public AccountController(ISafeClient<IAccountService> accountProxy)
{
_accountProxy = accountProxy;
}
I'm using Asp.net MVC 5 with Autofac integration, here are the registrations in my Global.asax Application_Start method.
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<AccountProxy>().As<IAccountService>().InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(SafeClient<,>)).As(typeof(ISafeClient<>)).InstancePerLifetimeScope();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
Now when I try to browse to a page handled by the AccountController, I get the following exception in the URL.
None of the constructors found with
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type
'MyMvcApp.Controllers.AccountController' can be invoked with the
available services and parameters: Cannot resolve parameter
'Project.Client.Proxies.ISafeClient`1[Project.Client.Contracts.Service.IAccountService]
accountProxy' of constructor 'Void
I'm not sure what I'm missing here. When I look in the container's ComponentRegistry at runtime I see the Controllers and the AccountProxy. Thanks in advance.
Update:
I can inject an IAccountService successfully if I register it like this instead:
builder.Register(a => new AccountProxy("userName", "password")).As<IAccountService>();
However when I try to inject the ISafeClient I still get an exception. I think I have a larger problem here. Essentially, I'm trying to wrap a ClientBase to include safe disposing and retry logic. It handles communication and message exceptions, faulted channel states, etc. Every time I execute a method on my SafeClient, the ClientBase is re-instantiated, then automatically disposed of. If this is the case, should I even be injecting it? Ugghh.. I'm confused.
Update 2:
Looks like I can just register like this.
builder.RegisterType<SafeClient<AccountProxy, IAccountService>>().As<ISafeClient<IAccountService>>().InstancePerLifetimeScope();
Then my AccountController changes to this:
private readonly ISafeClient<IAccountService> _accountProxy;
public AccountController(ISafeClient<IAccountService> accountProxy)
{
_accountProxy = accountProxy;
}
Is there any downside to doing it this way, other than the obvious which is having to register teach safe client individually?

Onion Architecture - Service Layer Responsibility

I am learning Onion Architecture by Jeffrey Palermo for more than 2 weeks now. I have created a test project by following this tutorial. While studying I came across this question on SO. According to accepted answer, one person nwang suggests that Methods like GetProductsByCategoryId should not be in Repository and one the other hand Dennis Traub
suggests that it is the responsibility of the Repository. What I am doing is :
I have a General Repository in Domain.Interface in which I have a method Find :
public interface IRepository<TEntity> where TEntity : class
{
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> filter = null);
.......
.......
.......
}
Then I created a BaseRepository in Infrastucture.Data:
public class RepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class
{
internal readonly DbSet<TEntity> dbSet;
public virtual IEnumerable<TEntity> Find(
Expression<Func<TEntity, bool>> filter = null)
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
return query.ToList();
}
}
And I have a concrete repository in Infrastructure.Data
public class ProductRepository : RepositoryBase<Product>, IProductRepository
{
public ProductRepository(MyDBContext context)
: base(context)
{
}
}
Now what I am doing in my Service Layer is Injecting Repository into Service and calling Repository.Find for methods like GetProductsByCategoryId. Like :
public class ProductService : IProductService
{
private readonly IUnitOfWork _unitOfWork;
private readonly IProductRepository _productRepository;
public ProductService(IUnitOfWork unitOfWork, IProductRepository productRepository)
{
_unitOfWork = unitOfWork;
_productRepository = productRepository;
}
public IList<Product> GetProductsByCategoryId(int CategoryId)
{
// At the moment, My code is like this:
return _productRepository.Find(e => e.CategoryId == CategoryId).ToList();
// My confusion is here. Am I doing it right or I need to take this code to
// ProductRepository and call _productRepositoy.GetProductsByCategoryId(CategoryId) here instead.
// If I do this, then Service Layer will become more of a wrapper around repository. Isn't it?
// My question is : What exactly will be the responsibility of the Service Layer in Onion Architecture?
}
}
The way you designed your application is ok... but only if your service will come to handle other things than just wrap up the repository methods!
Always keep in mind the YAGNI principle that says:
Always implement things when you actually need them, never when you just foresee that you need them
Let's say that you have a user story that says that whenever a product description is not found in your DB, you should retreive it from somewhere else (calling an external service or something). Then it seems obvious that your ProductService will have to have a
private readonly IProductRepository _productRepository;
but also a
private readonly IProductDescriptionService _productDescriptionService;
In that situation it really makes sense to add a service layer on top of your repositories.
I find that sometimes things can get over abstracted for the sake of it and offer no real value. I would say that the structure in your example is fine and follows the pattern correctly. Your service layer, correctly, is acting to serve the needs of the client UI, it is loosely coupled to the data layer and contains any business logic needed to manipulate the data.
I always think it is more productive to start simple and build upon your structure than it is to over abstract, over complicate and over bloat a project. A business or technical case will often drive the project, and dictate whether it is needed.
Although, in this case it seems that service later is just a wrapper, sometimes you might have the need to add some business logic or call two repositories. Lets say you have a service called CartService and you have a method called AddToCart in which you need to first get the product, do some calculation and then call insert to another repository like below.
public class CartService : ICartService
{
private readonly IUnitOfWork _unitOfWork;
public CartService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public void AddToCart (int productId, int quantity)
{
var product = _unitOfWork.ProductRepository
.Find(p => p.ProductId == productId).Single();
var cartItem = new CartItem {
ProductId = productId,
Desc = product.Desc,
Quantity = quantiry
};
_unitOfWork.CartRepository.Add(cartItem);
}
}
More, complex scenarios include calling a third party web service etc.

UoW & Repository + Service Layer

I'm using the following T4 to create my Repository & UoW:
http://blogs.microsoft.co.il/blogs/gilf/archive/2010/07/05/repository-and-unit-of-work-t4-template-for-entity-framework.aspx
Now I'm trying to add a Service Layer. I was able to accomplish something like this:
public ActionResult Index()
{
using (DataEntities context = new DataEntities())
{
UnitOfWork uow = new UnitOfWork(context);
//Service
ClientService cli = new ClientService(uow);
var col = cli.getActive();
//Map results to ViewModel
var list = AutoMapper.Mapper.Map<IEnumerable<Client>, IEnumerable<ClientListViewModel>>(col);
return View(list);
}
}
This works fine, but...
Is architecturally correct to pass the UoW instance to the Service Layer?
(I'm using IUnitOfWork in its ctor)
I tried to move the context & UoW inside the service layer, but the context is not available when I try to map the results to ViewModel in the controller.
Thanks!
I would argue no it isn't. Then again, I'm not a huge fan of unit of work -- I feel like it knows too much. I would pass the necessary repository(ies) to the service you create. Typically, I end up with special "GetService" or "CreateService" but this might work for you... (I'm writing this freehand so it might not build)
Public class DoSomethingCoolService : IDoSomethingCoolService
{
private IRepository<SomethingINeed> _neededRepository;
public DoSomethingCoolService(connectionOrContext)
{
//setup
}
public DoSomethingCoolService(IRepository<SomethingINeed> neededRepository)
{
_neededRepository = neededRepository;
}
public List<SomethingINeed> ReturnWhatIWant()
{
_neededRepository.Where(x => x.WhatIWant = true);
}
}
Personally, I don't like this. I prefer something more like this ...
public interface IGetService<T>
{
//usual get suspects here
}
public class GetService<T> : IGetService<T>
{
private IRepository<T> _repository;
GetService(IRepository<T> repository)
//use repository to call gets
}
now for the complicated-ish stuff...
public interface IGetClientService : IGetService<Client>
{
List<Client> GetClientsForSomething(int someId);
}
public class GetClientService : GetService<Client>, IGetClientService
{
private IRepository<Client> _repository;
GetClientService(IRepository<Client> repository) : base(repository)
public List<Client> GetClientsForSomething(int someId)
{
//some crazy cool business logic stuff here you want to test!
}
}
Then inside my controller, I just have a dependency on the IGetClientService, and use it where necessary. Easy to test, easy to make another that isn't dependent on it.
Does this make any sense?

Questions about the Service Layer as Validation in asp.net mvc

I am a bit confused about the service layer and using it validation.
So I am looking through this tutorial: http://www.asp.net/learn/mvc/tutorial-38-cs.aspx
First if you look at List 3
using System.Collections.Generic;
using System.Web.Mvc;
namespace MvcApplication1.Models
{
public class ProductService : MvcApplication1.Models.IProductService
{
private ModelStateDictionary _modelState;
private IProductRepository _repository;
public ProductService(ModelStateDictionary modelState, IProductRepository repository)
{
_modelState = modelState;
_repository = repository;
}
protected bool ValidateProduct(Product productToValidate)
{
if (productToValidate.Name.Trim().Length == 0)
_modelState.AddModelError("Name", "Name is required.");
if (productToValidate.Description.Trim().Length == 0)
_modelState.AddModelError("Description", "Description is required.");
if (productToValidate.UnitsInStock < 0)
_modelState.AddModelError("UnitsInStock", "Units in stock cannot be less than zero.");
return _modelState.IsValid;
}
public IEnumerable<Product> ListProducts()
{
return _repository.ListProducts();
}
public bool CreateProduct(Product productToCreate)
{
// Validation logic
if (!ValidateProduct(productToCreate))
return false;
// Database logic
try
{
_repository.CreateProduct(productToCreate);
}
catch
{
return false;
}
return true;
}
}
public interface IProductService
{
bool CreateProduct(Product productToCreate);
IEnumerable<Product> ListProducts();
}
}
They same interface just with a different name basically why not just use one?
public interface IProductRepository
{
bool CreateProduct(Product productToCreate);
IEnumerable<Product> ListProducts();
}
public interface IProductService
{
bool CreateProduct(Product productToCreate);
IEnumerable<Product> ListProducts();
}
In my book though(the author who I think wrote this tutorial) has changed it to have IProductRepository to void. So that confuses me even more.
So can someone explain why I need 2 interfaces that seems to do the same thing?
My next questions is my repository has a delete function. Do I put this one in my Service layer too(I guess mandatory if you use one Interface but if you use 2 like about then it could be optinal).
So what would I have in my service layer? Would it just call delete function in the repository? Should it just be a void method or should it return bool? I don't think for this method any validation would need to be done?
So I am not sure if a bool would be needed.
From the tutorial you are reading:
So, application flow control logic
belongs in a controller and data
access logic belongs in a repository.
In that case, where do you put your
validation logic? One option is to
place your validation logic in a
service layer.
A service layer is an additional layer
in an ASP.NET MVC application that
mediates communication between a
controller and repository layer. The
service layer contains business logic.
In particular, it contains validation
logic.
EDIT:
I'm not sure if I can explain it to you in a clear way('cause I'm not fluent in English), but I will try:
A service layer is an additional layer in an ASP.NET MVC application that mediates communication between a controller and repository layer, in that you can handle both validation and application businness. Sometimes you service will need to work with two or more methods of its correspondent repository layer so it doesnt need to have the same interface.
A basic example, let's think you have a register form.
you will have the following interfaces
public interface IUserService
{
bool Register(User mUser);
bool Validate(User mUser);
}
public interface IUserRepository
{
User FindUserByEmail(string Email);
bool Insert(User mUser);
}
so you will end up with two class that will do something like:
public class UserRepository: IUserRepository{
User FindUserByEmail(string Email)
{
//do a ninja search and return an user or null
}
bool Insert(User mUser);
{
//Insert user into db
}
}
public class UserService: IUserService
{
public bool Validate(User mUser)
{
//validate user
}
IUserRepository _respository = new UserRepository();
bool Register(User mUser)
{
if(Validate(mUser);
var hasUser = _respository.FindUserByEmail(User.Email);
if(hasUser==null)
return _respository.Insert(mUser);
return false;
}
}
I think you've made an argument for a single interface in this limited case, but the service and repositories perform two very different functions and you may run into issues down the road if they shared a single interface.
What if the CreateProduct() or ListProducts() needed to have different method signatures in either the service or repository?
What if ValidateProduct() should be defined in the interface? The repository certainly shouldn't have to implement that.
As you've pointed out, there's no need for two interfaces that define the same thing in this particular example, but I assume the author's assumption is that down the road they would be different and therefore necessary.

Resources