I have the following problem - or rather, an urgent need for valuable advice - with Microsoft MVC. A certain action from the client leads to the creation of:
A remark in the table Remarks
An entry in the table for HourRegistrations
An entry in the changelog for Tickets
I use a service layer for business actions and repositories for CRUD actions. The problem is that I at times need to connect objects from different DataContexts so I suppose I use a flawed design. Recently we have started to remove all business logic from our controllers and repositories and this is one of the first things I run into.
Example:
BLogic.AddRemarks(Ticket t, ...)
{
Remark r = _remarksRepository.Create();
r.Ticket = t;
_remarksRepository.Add(r);
_remarksRepository.Save();
}
This triggers kBOOM since the Ticket is fetched in the controller using the repository. So Remark r and Ticket t do not share the same data context.
I can alter the signature of the method and provide an int TicketId, but that doesn't feel right. Besides, I then get similar problems further down the line.
My repositories are created at the constructor of the service class. Perhaps I must create them at the start of a method? Even then, I must often transfer Ids instead of the true objects.
My suggestion is to use dependeny injection (or inversion of control - depends how would you like to call it). I use myself castle windor. Really simple to integrate with mvc.net. read more
When IoC is up and running create ContextManager. Somethig like this:
public class ContextManager : IContextManager
{
private XContext context;
public XContext GetContext()
{
return context ?? (context = XContext.Create());
}
}
Set IContextManager lifestyle as perwebrequest and you got yourself context that you can access from repositories and services. and it's same per one request.
EDIT
You also have to create your own controllerFactory
then you can use your services and repositories like this:
public class MyController : Controller
{
public ISomeService SomeService { get; set; }
public IContextManager ContextManager { get; set; }
...
}
You dont have to create new instances for services and repositories and you can manage those objects lifestyle from configuration. Most reasonable would be singleton
Related
Working with WebAPI ODATA services with javascript is not a problem... but what is a current recommendation to wrap the http calls (CRUD) to be consumed through a MVC5 application with a repository. Much of the guidance I see ultimately goes directly to the entity/dbcontext. I am looking for guidance which demonstrates the "drinking of your own Kool-Aid" and consuming the same ODATA (and it can be plain WebAPI, also) published externally to consumers of an application.
In my mind, I'm looking at this sort of flow:
AppController (site1:443)-->AppRepository-->OdataController (apiSite2:443)-->OdataRepository-->DataSource
The secondary concern is that I don't necessarily want direct access to a datasource by any consumer--especially posts without being vetted and I don't want all (any) of the logic in the controller. I might be overthinking something...
In order to extract the business logic from the controller I typically either push said logic down to domain objects whenever possible. If that isn't possible, then I'll create a class specifically designed to manage the logic in question, such as an interaction between two different objects.
If all else fails, then I'll have the interaction managed by a service. The classes might look something like the following:
public class SomeApiController : ApiController
{
public SomeApiController(ISomeApiService service)
{
this.Service = service;
}
private ISomeApiService Service { get; set; }
public IHttpActionResult SomeMethod(int someObjectId)
{
// service manages the logic and either defers to the object in question or resolves it through some specialized class
var result = this.Service.SomeMethod(someObjectId);
return this.OK(result);
}
}
public class SomeApiService : ISomeApiService
{
public SomeApiService(ISomeRepository repository)
{
this.Repository = repository;
}
private ISomeRepository Repository { get; set; }
}
... and so on.
The idea being that the layers have no dependencies upon one another which cannot be resolved through the IoC container of your choice and that the dependencies only go one way. That is to say SomeApiService has no dependency on SomeApiController and SomeApiRepository would have no dependency on SomeApiService.
I need to implement MVC architecture in my company, So can anyone suggest where to keep frequently used methods to call on all pages. Like:
states ddl, departments ddl also roles list and etc...
Please give me suggestions where to keep them in architecture.
Thanks
There are different solutions depending on the scale of your application. For small projects, you can simply create a set of classes in MVC application itself. Just create a Utils folder and a DropDownLists class and away you go. For simple stuff like this, I find it's acceptable to have static methods that return the data, lists, or enumerations you require.
Another option is to create an abstract MyControllerBase class that descends from Controller and put your cross-cutting concerns in there, perhaps as virtual methods or properties. Then all your actual controllers can descend from MyControllerBase.
For larger applications, or in situations where you might share these classes with other MVC applications, create a shared library such as MySolution.Utils and reference the library from all projects as required.
Yet another possibility for larger solutions is to use Dependency Injection to inject the requirements in at runtime. You might consider using something like Unity or Ninject for this task.
Example, as per your request (also in GitHub Gist)
// declare these in a shared library
public interface ILookupDataProvider
{
IEnumerable<string> States { get; }
}
public class LookupDataProvider: ILookupDataProvider
{
public IEnumerable<string> States
{
get
{
return new string[] { "A", "B", "C" };
}
}
}
// then inject the requirement in to your controller
// in this example, the [Dependency] attribute comes from Unity (other DI containers are available!)
public class MyController : Controller
{
[Dependency]
public ILookupDataProvider LookupDataProvider { get; set; }
public ActionResult Index()
{
var myModel = new MyModel
{
States = LookupDataProvider.States
};
return View(myModel);
}
}
In the code above, you'll need to configure your Dependency Injection technology but this is definitely outside the scope of the answer (check SO for help here). Once configured correctly, the concrete implementation of ILookupDataProvider will be injected in at runtime to provide the data.
One final solution I would suggest, albeit this would be very much overkill for small projects would be to host shared services in a WCF service layer. This allows parts of your application to be separated out in to highly-scalable services, should the need arise in the future.
I have an asp.net-mvc website and i am using ninject for IOC and nhibernate for my ORM mapping
Here is my IOC binding code:
internal class ServiceModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IIntKeyedRepository<>)).To(typeof(Repository<>)).InRequestScope();
}
}
and here is an example of how I am doing IOC into my controller code:
public FAQController(IIntKeyedRepository<FAQ> faqRepository, IUnitOfWork unitOfWork)
{
_faqRepository = faqRepository;
_unitOfWork = unitOfWork;
}
The issue is that up until now, each controller had a single table that it was pointing to so i only needed on repository class passed into it...
Now, I have a number of tables and classes that are all just have 2 fields:
Id
Name
for each of these classes, i simply inherit from a base class called:
BaseModel
which is just:
public class BaseModel
{
public virtual string Name { get; set; }
public virtual int Id { get; set; }
}
I want to have one:
StaticDataController
class that can do all of the CRUD for every class that simply inherits from BaseModel (with no extra fields)
The dumb simple way would be to do this:
private readonly IIntKeyedRepository<Object1> _object1Repository;
private readonly IIntKeyedRepository<Object2> _object2Repository;
private readonly IIntKeyedRepository<Object3> _object3Repository;
private readonly IIntKeyedRepository<Object4> _object4Repository;
private readonly IIntKeyedRepository<Object5> _object5Repository;
public StaticDataController(IIntKeyedRepository<Object1> obj1Repository, IIntKeyedRepository<Object2> obj2Repository, IIntKeyedRepository<Object3> obj3Repository, IIntKeyedRepository<Object4> obj4Repository, IIntKeyedRepository<Object5> obj5Repository)
{
_obj1Repository= obj1Repository;
_obj2Repository= obj2Repository;
_obj3Repository= obj3Repository;
_obj4Repository= obj4Repository;
_obj5Repository= obj5Repository;
}
Since I am passing the table in as a parameter to my methods, I would have to have some switch statement in my controller to get the right repository class based on the string of the parameter.
I assume there must be a much more elegant way to support what I am trying to do so I wanted to see if there is any best practice here (controller inheritance, reflection, etc.)?
If you need to do this it means that your controller does too many things and a strong indication that it requires a service layer. In this case I deport those repositories into the service layer. So my controller takes a service instead of multiple repositories:
private readonly IStatisticDataService _service;
public StaticDataController(IStatisticDataService service)
{
_service = service;
}
The service has business that could be composed of multiple atomic repository CRUD methods.
I know that you might say: yes, but now I have to inject all those repositories into the implementation of the IStatisticDataService interface. Yes, but it would make more sense to aggregate those atomic CRUD operations into the service layer rather than the controller.
But if need 5 or more repositories in order to perform a some business operations, maybe you have to rethink your domain architecture. Probably you could use composition in your domain models and define relations between them in order to reduce the number of repositories. It's difficult to provide more concrete advice without knowing the specifics of your domain.
Now, I have a number of tables and classes that are all just have 2 fields:
Great, make them derive all from the same base domain model and have a single repository to serve them. You could use descriminator columns, etc...
Darin is absolutely right. I'd just like to add though, if you're using MVC 3, you should be using the Ninject.MVC3 nuget package rather than creating your own Service Module.
As Mark Seemann mentioned: "It's quite OK, but once you feel that the Controller becomes too cluttered, you can refactor its dependencies to an Aggregate Service."
Look at: BestPractices: Is it acceptable to use more than one repository in a MVC-Controller?
In OOP Design Patterns, what is the difference between the Repository Pattern and a Service Layer?
I am working on an ASP.NET MVC 3 app, and am trying to understand these design patterns, but my brain is just not getting it...yet!!
Repository Layer gives you additional level of abstraction over data access. Instead of writing
var context = new DatabaseContext();
return CreateObjectQuery<Type>().Where(t => t.ID == param).First();
to get a single item from database, you use repository interface
public interface IRepository<T>
{
IQueryable<T> List();
bool Create(T item);
bool Delete(int id);
T Get(int id);
bool SaveChanges();
}
and call Get(id). Repository layer exposes basic CRUD operations.
Service layer exposes business logic, which uses repository. Example service could look like:
public interface IUserService
{
User GetByUserName(string userName);
string GetUserNameByEmail(string email);
bool EditBasicUserData(User user);
User GetUserByID(int id);
bool DeleteUser(int id);
IQueryable<User> ListUsers();
bool ChangePassword(string userName, string newPassword);
bool SendPasswordReminder(string userName);
bool RegisterNewUser(RegisterNewUserModel model);
}
While List() method of repository returns all users, ListUsers() of IUserService could return only ones, user has access to.
In ASP.NET MVC + EF + SQL SERVER, I have this flow of communication:
Views <- Controllers -> Service layer -> Repository layer -> EF -> SQL Server
Service layer -> Repository layer -> EF This part operates on models.
Views <- Controllers -> Service layer This part operates on view models.
EDIT:
Example of flow for /Orders/ByClient/5 (we want to see order for specific client):
public class OrderController
{
private IOrderService _orderService;
public OrderController(IOrderService orderService)
{
_orderService = orderService; // injected by IOC container
}
public ActionResult ByClient(int id)
{
var model = _orderService.GetByClient(id);
return View(model);
}
}
This is interface for order service:
public interface IOrderService
{
OrdersByClientViewModel GetByClient(int id);
}
This interface returns view model:
public class OrdersByClientViewModel
{
CientViewModel Client { get; set; } //instead of ClientView, in simple project EF Client class could be used
IEnumerable<OrderViewModel> Orders { get; set; }
}
This is interface implementation. It uses model classes and repository to create view model:
public class OrderService : IOrderService
{
IRepository<Client> _clientRepository;
public OrderService(IRepository<Client> clientRepository)
{
_clientRepository = clientRepository; //injected
}
public OrdersByClientViewModel GetByClient(int id)
{
return _clientRepository.Get(id).Select(c =>
new OrdersByClientViewModel
{
Cient = new ClientViewModel { ...init with values from c...}
Orders = c.Orders.Select(o => new OrderViewModel { ...init with values from o...}
}
);
}
}
As Carnotaurus said the repository is responsible for mapping your data from the storage format to you business objects. It should handle both how to read and write data(delete, update too) from and to the storage.
The purpose of service layer on the other hand is to encapsulate business logic into a single place to promote code reuse and separations of concerns. What this typically means for me in practice when building Asp.net MVC sites is that I have this structure
[Controller] calls [Service(s)] who calls [repository(ies)]
One principle I have found useful is to keep logic to a minimum in controllers and repositories.
In controllers it is because it helps keeping me DRY. It's very common that I need to use the same filtering or logic somewhere else and if I placed it in the controller I can't reuse it.
In repositories it is because I want to be able to replace my storage(or ORM) when something better comes along. And if I have logic in the repository I need to rewrite this logic when I change the repository. If my repository only returns IQueryable and the service does the filtering on the other hand, I will only need to replace the mappings.
For example I recently replaced several of my Linq-To-Sql repositories with EF4 and those where I had stayed true to this principle could replaced in a matter of minutes. Where I had some logic it was a matter of hours instead.
The accepted answer (and upvoted hundreds of time) has a major flaw. I wanted to point this out in the comment but it will just get buried down there in 30 something comments so pointing out here.
I took over an enterprise application which was built that way and my initial reaction was WTH? ViewModels in service layer? I did not want to change the convention because years of development had gone into it so I continued with returning ViewModels. Boy it turned into a nightmare when we started using WPF. We (the team of devs) were always saying: which ViewModel? The real one (the one we wrote for the WPF) or the services one? They were written for a web application and even had IsReadOnly flag to disable edit in the UI. Major, major flaw and all because of one word: ViewModel!!
Before you make the same mistake, here are some more reasons in addition to my story above:
Returning a ViewModel from the service layer is a huge no no. That's like saying:
If you want to use these services you better be using MVVM and here is the ViewModel you need to use. Ouch!
The services are making the assumption they will be displayed in a UI somewhere. What if it is used by a non UI application such as web services or windows services?
That is not even a real ViewModel. A real ViewModel has observability, commands etc. That is just a POCO with a bad name. (See my story above for why names matter.)
The consuming application better be a presentation layer (ViewModels are used by this layer) and it better understand C#. Another Ouch!
Please, don't do that!
Repository layer is implemented to access the database and helps to extend the CRUD operations on the database. Whereas a service layer consists of the business logic of the application and may use the repository layer to implement certain logic involving the database. In an application, it is better to have a separate repository layer and service layer. Having separate repository and service layers make the code more modular and decouple the database from business logic.
Usually a repository is used as scaffolding to populate your entities - a service layer would go out and source a request. It is likely that you would put a repository under your service layer.
I'm making a start on an MVC project, having gone through the MvcMusicStore tutorial. I'm trying to get my head around how the POCO-generated data/entity context is intended to be stored.
In the samples, the controller generates a copy of the entity context, and all operations complete there:
MusicStoreEntities storeDB = new MusicStoreEntities();
//
// GET: /Store/
public ActionResult Index()
{
// Retrieve list of Genres from database
var genres = from genre in storeDB.Genres
select genre.Name;
[...]
If I'm to split my solution into layers, what is the standard practice (or key options) for retaining the context? Do I generate it in the controller, and pass it to the repository, or is it possible for the repository to keep a general-use copy?
I understand that the the above would be necessary to use the Unit of Work pattern.
My layers are:
Data (edmx file)
Entities (Generated from POCO)
Repository
Mvc web app
My other questions:
- What is the overhead of generating the context?
- As there is no .Close(), and it doesn't implement IDisposable, is the ObjectContext behind it generating individual connections, connection pooling, sharing a single instance?
- Is it possible to lock an ObjectContext if it's passed around between layers / operations too much?
Thanks in advance.
I don't want to go into too much detail/code here, so i'll just mention some points:
Your controller can work with multiple repositories
There should be one repository per aggregate root
Controller work amongst multiple repositories are made possible by Unit of Work
Use a DI container to handle lifetime management of Unit of Work (which is actually the context)
Do not use singletons for the Context, let the DI container instantiate/dispose of the context per HTTP request
I create a single repository for each controller and put my context in there. The rules I follow are that the repository handles anything that I might want to mock (not really the definition of repository, but it works for me). The repository can call other repositories if necessary, but the controller shouldn't have to know about it. The Context is an instance property of the repository and is created on demand (I haven't taken the leap into IOC yet). If the repository calls another repository, it passes the Context instance.
It looks a little like this...
public class MyController : Controller
{
public IMyControllerRepository Repository { get; set; }
public ActionResult MyAction(int id)
{
var model = Repository.GetMyModel(id);
return View(model);
}
}
public class MyControllerRepository : IMyControllerRepository
{
public MyContext Context { get; set; };
public MyModel GetMyModel(int id)
{
return (from m in Context.MyModels
where m.ID = id
select m).SingleOrDefault();
}
}