Java or dotNet world is rich of open source frameworks and libraries. We all like to use Spring and Hibernate almost everywhere.
Everyone agrees that hibernate is a very handy tool.
What Hibernate can do ? well, Basically - Hibernate can track our domain objects changes and persist only modified data to database, that is it.
Basically, That is everything we want. I want to load some records from database, do some modifications to them, and call transaction.commit(), and all modifications get persisted, instantaneously.
That is excelent, right !
But how about web world ? In web applications database session must be closed.
I cannot load some domain objects and wait for user to do modifications through HTTP, and persist those objects after modifications.
We have to use detached objects or DTO. How it works ?
User makes modifications in HTML browser, spring Mvc automatically thransfers those HTML modifiactions to our customized DTO objects using MVC model binding,
then we do some programming effort to transfer modifications from DTO objects to hibernate domain objects and only then we persist them.
For example - we have a web form that updates Customer address, and another form which updates customer details.
We must have two different business layer methods - UpdateAddress() and UpdateDetails(), both methods must accept some kind of DTO,
one represents address information, the other represents details infprmation.
We also have custom logic that transfers data from those 2 DTO to the domain class 'Customer'.
Yes, of course, instead of DTO objects we could reuse our domain classes. But it does not make it simpler.
In both cases we will still have to implement custom logic that transfer modifications to persistent objects,
I cannot persist detached object rightaway, because usually domain classes have lots and lots of properties representing numerous relations, for ex. Customer has - Orders property. When I update customer address I don't want to update its orders.
Is there a beautifull universal way to mapping modifications from mvc model to domain objects without writing a lot of custom code and without risk of overwriting too many fields ?
It's good practice to have a data access layer, which translates into having a repository for each domain object / entity. Furthermore, all repositories share common code so you you naturally have an abstract repository:
public abstract class AbstractRepository<E extends BaseModel> implements Repository<E> {
#PersistenceContext
private EntityManager entityManager;
private Class<E> entityClass;
public AbstractRepository(Class<E> entityClass) {
this.entityClass = entityClass;
}
protected EntityManager getEM() {
return entityManager;
}
protected TypedQuery<E> createQuery(String jpql) {
return createQuery(jpql, entityClass);
}
protected <T> TypedQuery<T> createQuery(String jpql, Class<T> typeClass) {
return getEM().createQuery(jpql, typeClass);
}
#Override
public E merge(E entity) {
return getEM().merge(entity);
}
#Override
public void remove(E entity) {
getEM().remove(entity);
}
#Override
public E findById(long id) {
return getEM().find(entityClass, id);
}
}
It's also good practice to have a service layer where you are to create, update and delete instances of an entity (where you could pass through a DTO to the create and update methods if you so desire).
...
#Inject
private CustomerRepository customerRepository;
public Customer createCustomer(CustomerDto customerDto) {
Customer customer = new Customer();
customer.setEmail(customerDto.getEmail());
...
return customerRepository.merge(customer);
}
public Customer updateCustomerAddress(Customer customer, String address) {
customer.setAddress(address);
return customerRepository.merge(customer);
}
...
So it's up to you how many update methods you want. I would typically group them into common operations such as updating the customer's address, where you would pass the customer Id and the updated address from the front end (probably via ajax) to your controller listening on a specific endpoint. This endpoint is where you would use the repository to find the entity first by Id and then pass it to your service to do the address update for example.
Lastly you need to ensure that the data actually gets persisted, so in Spring you can add the #Transactional annotation either to you Spring MVC controller or to your service that does the persisting. I'm not aware of any best practices around this but I prefer adding it to my controllers so that you're always guaranteed to have a transaction no matter what service you are in.
Related
I'm trying to use NHibernate for a new app with a legacy database. It's going pretty well but I'm stuck and can't find a good solution for a problem.
Let's say I have this model :
a Service table (Id, ServiceName..)
a Movie table (Id, Title, ...)
a Contents table which associates a service and a movie (IdContent, Name, IdMovie, IdService)
So I mapped this and it all went good. Now I can retrieve a movie, get all the contents associated, ...
My app is a movies shop "generator". Each "service" is in fact a different shop, when a user enter my website, he's redirected to one of the shops and obviously, I must show him only movies available for his shop. The idea is : user comes, his service is recognized, I present him movies which have contents linked to his service. I need to be able to retrieve all contents for a movie for the backoffice too.
I'm trying to find the most transparent way to accomplish this with NHibernate. I can't really make changes to the db model.
I thought about a few solutions :
Add the service condition into all my queries. Would work but it's a bit cumbersome. The model is very complex and has tons of tables/queries..
Use nhibernate filter. Seemed ideal and worked pretty good, I added the filter on serviceid in all my mappings and did the EnableFilter as soon as my user's service was recognized but.. nhibernate filtered collections don't work with 2nd lvl cache (redis in my case) and 2nd lvl cache usage is mandatory.
Add computed properties to my object like Movie.PublishedContents(Int32 serviceId). Probably would work but requires to write a lot of code and "pollutes" my domain.
Add new entities inheriting from my nhibernate entity like a PublishedMovie : Movie wich only presents the contextual data
None of these really satisfies me. Is there a good way to do this ?
Thanks !
You're asking about multi-tenancy with all the tenants in the same database. I've handled that scenario effectively using Ninject dependency injection. In my application the tenant is called "manual" and I'll use that in the sample code.
The route needs to contain the tenant e.g.
{manual}/{controller}/{action}/{id}
A constraint can be set on the tenant to limit the allowed tenants.
I use Ninject to configure and supply the ISessionFactory as a singleton and ISession in session-per-request strategy. This is encapsulated using Ninject Provider classes.
I do the filtering using lightweight repository classes, e.g.
public class ManualRepository
{
private readonly int _manualId;
private readonly ISession _session;
public ManualRepository(int manualId, ISession session)
{
_manualId = manualId;
_session = session;
}
public IQueryable<Manual> GetManual()
{
return _session.Query<Manual>().Where(m => m.ManualId == _manualId);
}
}
If you want pretty urls you'll need to translate the tenant route parameter into its corresponding database value. I have these set up in web.config and I load them into a dictionary at startup. An IRouteConstraint implementation reads the "manual" route value, looks it up, and sets the "manualId" route value.
Ninject can handle injecting the ISession into the repository and the repository into the controller. Any queries in the controller actions must be based on the repository method so that the filter is applied. The trick is injecting the manualId from the routing value. In NinjectWebCommon I have two methods to accomplish this:
private static int GetManualIdForRequest()
{
var httpContext = HttpContext.Current;
var routeValues = httpContext.Request.RequestContext.RouteData.Values;
if (routeValues.ContainsKey("manualId"))
{
return int.Parse(routeValues["manualId"].ToString());
}
const string msg = "Route does not contain 'manualId' required to construct object.";
throw new HttpException((int)HttpStatusCode.BadRequest, msg);
}
/// <summary>
/// Binding extension that injects the manualId from route data values to the ctor.
/// </summary>
private static void WithManualIdConstructor<T>(this IBindingWithSyntax<T> binding)
{
binding.WithConstructorArgument("manualId", context => GetManualIdForRequest());
}
And the repository bindings are declared to inject the manualId. There may be a better way to accomplish this through conventions.
kernel.Bind<ManualRepository>().ToSelf().WithManualIdConstructor();
The end result is that queries follow the pattern
var manual = _manualRepository
.GetManual()
.Where(m => m.EffectiveDate <= DateTime.Today)
.Select(m => new ManualView
{
ManualId = m.ManualId,
ManualName = m.Name
}).List();
and I don't need to worry about filtering per tenant in my queries.
As for the 2nd level cache, I don't use it in this app but my understanding is that you can set the cache region to segregate tenants. This should get you started: http://ayende.com/blog/1708/nhibernate-caching-the-secong-level-cache-space-is-shared
Consider the following business entity class. In order to validate itself, it needs to know something about the state of the database, perhaps to prevent a conflict of some kind. So, it has a dependency on the data access layer in order to retrieve this data.
Is it a violation of the Single Responsibility Principle to have a class that encapsulates state, validates the state, and accesses a data store to do so?
class MyBusinessObject
{
private readonly IDataStore DataStore;
public MyBusinessObject(IDataStore dataStore)
{
this.DataStore = dataStore;
}
public virtual int? Id { get; protected set; }
public virtual string Name { get; set; }
// ... Other properties...
public IEnumerable<ValidationResult> Validate()
{
var data = this.DataStore.GetDataThatInfluencesValidation();
return this.ValidateUsing(data);
}
// ... ValidateUsing method would be in here somewhere ...
}
It's throwing a red flag for me because:
In the context of an ASP.NET MVC controller's Create method, I might make a new instance and pass it to my View() method with no intention of validating, so why should I be required to pass in an IDataStore?
I'm using NHibernate (and I'm a noob), and it looks like I have to create an IInterceptor that injects dependencies whenever NH creates entities. Maybe that will be fine, but it feels a little bit wrong to me.
I'm starting to think I should use an anemic/DTO type of object for NHibernate to use, and wrap that inside something else that knows all the business rules AND can access a data store if it depends on one. Now that I've typed up my question and title, StackOverflow has suggested some interesting resources: here and here.
My question also looks very similar to this one, but I thought I'd ask it in a different way that more closely matches my situation.
"Is it a violation of the Single Responsibility Principle to have a class that encapsulates state, validates the state, and accesses a data store to do so?" -- You listed three responsibilities so I'm going to answer yes.
The difficulty with validation is that it depends on context. For example, creating a customer record might require just their name but selling them a product requires payment information and a shipping address.
IN MVC, I do low level (data sizes and nullability) validation using data annotations in view models. More complex validation is done using the specification pattern. The specification pattern is easy to implement and flexible.
I've made a custom model, and I want to mock it. I'm fairly new to MVC, and very new to unit testing. Most approaches I've seen create an interface for the class and then make a mock that implements the same interface. However I can't seem to get this to work when actually passing the interface into the View. Cue "simplified" example:
Model-
public interface IContact
{
void SendEmail(NameValueCollection httpRequestVars);
}
public abstract class Contact : IContact
{
//some shared properties...
public string Name { get; set; }
public void SendEmail(NameValueCollection httpRequestVars = null)
{
//construct email...
}
}
public class Enquiry : Contact
{
//some extra properties...
}
View-
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<project.Models.IContact>" %>
<!-- other html... -->
<td><%= Html.TextBoxFor(model => ((Enquiry)model).Name)%></td>
Controller-
[HttpPost]
public ActionResult Index(IContact enquiry)
{
if (!ModelState.IsValid)
return View(enquiry);
enquiry.SendEmail(Request.ServerVariables);
return View("Sent", enquiry);
}
Unit Testing-
[Test]
public void Index_HttpPostInvalidModel_ReturnsDefaultView()
{
Enquiry enquiry = new Enquiry();
_controller.ModelState.AddModelError("", "dummy value");
ViewResult result = (ViewResult)_controller.Index(enquiry);
Assert.IsNullOrEmpty(result.ViewName);
}
[Test]
public void Index_HttpPostValidModel_CallsSendEmail()
{
MockContact mock = new MockContact();
ViewResult result = (ViewResult)_controller.Index(mock);
Assert.IsTrue(mock.EmailSent);
}
public class MockContact : IContact
{
public bool EmailSent = false;
void SendEmail(NameValueCollection httpRequestVars)
{
EmailSent = true;
}
}
Upon a HttpPost I get a "Cannot create an instance of an interface" exception. I seems that I can't have my cake (passing a model) and eat it (pass mock for unit testing). Maybe there's a better approach to unit testing models bound to views?
thanks,
Med
I'm going to throw it out there, if you need to mock your models you're doing it wrong. Your models should be dumb property bags.
There is absolutely no reason that your model should have a SendEmail method. That is functionality that should be invoked from a controller calling to an EmailService.
Responding to your question:
After years of working with Separation of Concern (SOC) patterns like MVC, MVP, MVVM and seeing articles from people brighter than me (I wish I could find the one I'm thinking off about this but maybe I read it in a magazine). You will eventually conclude in an enterprise application you will end up with 3 distinct sets of model objects.
Previously I was a very big fan of doing Domain Driven Design (DDD) using a single set of business entities that were both plain old c# objects (POCO) and Persistent Ignorant (PI). Having domain models that are POCO/PI leaves you with a clean slate of objects where there is no code related to accessing the object storage or having other attributes that have schematic meaning for only 1 area of the code.
While this works, and can work fairly well for a period of time, there is eventually a tipping point where the complexity of expressing the relationship between View, Domain Model, and Physical Storage Model becomes too complex to express correctly with 1 set of entities.
To solve the impedance mismatches of View, Domain and Storage you really need 3 sets of models. Your ViewModels will exactly match your views binding to facilitate it to be easy to work with the UI. So this will frequently have things such as adding a List to populate drop downs with values that are valid for your edit view/action.
In the middle is the Domain Entities, these are the entities that you should validate against your business rules. So you will map to/from them on both sides to/from the view and to/from the storage layer. In these entities is where you could attach your code to do validation. I personally am not a fan of using attributes and coupling validation logic into your domain entities. It does make alot of sense to couple validation attributes into your ViewModels to take advantage of the built in MVC client side validation functionality.
For validation I would recommend using a library like FluentValidation (or your own custom one, they're not hard to write) that lets you separate your business rules from your objects. Although with new features with MVC3 you can do remote validation severside and have it display client side, this is an option to handle true business validation.
Finally you have your storage models. As I said previously I was very zealous on having PI objects being able to be reused through all layers so depending on how you setup your durable storage you might be able to directly use your domain objects. But if you take advantage of tools like Linq2Sql, EntityFramework (EF) etc you will most likely have auto generated models with code for interacting with the data provider so you will want to map your domain objects to your persistence objects.
So wrap all of this up this would be a standard logic flow in MVC actions
User goes to edit product page
EF queries the database to get the existing product information, inside the repository layer the EF data objects are mapped to the Business Entities (BE) so all the data layer methods return BEs and have no external coupling to the EF data objects. (So if you ever change your data provider you don't have to alter a single line of code except for the internal implementation)
The controller gets the Product BE and maps it to a Product ViewModel (VM) and adds collections for the different options that can be set for drop down lists
Return View(theview, ProductVM)
User edits the product and submits the form
Client side validation is passed (useful for date validation / number validation instead of having to submit the form for feedback)
The ProductVM gets mapped back to ProductBE at this point you would validate the business rules along the lines ValidationFactory.Validate(ProductBE), if it's invalid return messages back to view and cancel edit, otherwise continue
You pass the ProductBE into your repository model, inside the internal implementation of the data layer you map the ProductBE to the Product Data Entity for EF and update the database.
2016 edit: removed usages of Interface as separation of concerns and interfaces are entirely orthogonal.
Your issue is here:
public ActionResult Index(IContact enquiry)
MVC in the background has to create a concrete type to pass to the method when calling it. In this method's case, MVC needs to create a type which implements IContract.
Which type? I dunno. Neither does MVC.
Instead of using interfaces in order to be able to mock your models, use normal classes that have protected methods which you can override in mocks.
public class Contact
{
//some shared properties...
public string Name { get; set; }
public virtual void SendEmail(NameValueCollection httpRequestVars = null)
{
//construct email...
}
}
public class MockContact
{
//some shared properties...
public string Name { get; set; }
public bool EmailSent {get;private set;}
public override void SendEmail(NameValueCollection vars = null)
{
EmailSent = true;
}
}
and
public ActionResult Index(Contact enquiry)
It is possible to use interfaces.
See: http://mvcunity.codeplex.com/
I'm developing an application using asp.net mvc, NHibernate and DDD. I have a service layer that are used by controllers of my application. Everything are using Unity to inject dependencies (ISessionFactory in repositories, repositories in services and services in controllers) and works fine.
But, it's very common I need a method in service to get only object in my repository, like this (in service class):
public class ProductService {
private readonly IUnitOfWork _uow;
private readonly IProductRepository _productRepository;
public ProductService(IUnitOfWork unitOfWork, IProductRepository productRepository) {
this._uow = unitOfWork;
this._productRepository = productRepository;
}
/* this method should be exists in DDD ??? It's very common */
public Domain.Product Get(long key) {
return _productRepository.Get(key);
}
/* other common method... is correct by DDD ? */
public bool Delete(long key) {
usign (var tx = _uow.BeginTransaction()) {
try
{
_productRepository.Delete(key);
tx.Commit();
return true;
} catch {
tx.RollBack();
return false;
}
}
}
/* ... others methods ... */
}
This code is correct by DDD ? For each Service class I have a Repository, and for each service class need I do a method "Get" for an entity ?
Thanks guys
Cheers
Your ProductService doesn't look like it followed Domain-Driven Design principles. If I understand it correctly, it is a part of Application layer between Presentation and Domain. If so, the methods on ProductService should have business meaning with regard to products.
Let's talk about deleting products. Is it as simple as executing delete on the database (NHibernate, or whatever?) I think it is not. What about orders which reference the to-be-deleted product? And so on and so forth. Btw, Udi Dahan wrote a great article on deleting entities.
Bottom line is, if your application is so simple that services do really replicate your repositories and contain only CRUD operations, you probably shouldn't do DDD, throw away your repositories and let services operate on entities (which would be simple data containers in that case).
On the other hand, if there is a complicated behavior (like the one with handling 'deleted' products), there is a point in going DDD path and I strongly advocate doing so.
PS. Despite which approach (DDD or not) you will eventually take I would encourage you to use some Aspect Oriented Programming to handle transaction and exception related stuff. You would end up with way to many methods such as DeleteProduct with same TX and exception handling code.
That looks correct from my perspective. I really didn't like repeating service and repository method names over and over in my asp.net MVC project, so I went for a generic repository approach/pattern. This means that I really only need one or two Get() methods in my repository to retrieve my objects. This is possible for me because I am using Entity Framework and I just have my repository's get() method return a IQueryable. Then I can just do the following:
Product product = from p in _productRepository.Get() where p.Id == Id select p;
You can probably replicate this in NHibernate with linq -> NHibernate.
Edit: This works for DDD because this still allows me to interchange my DAL/repositories as long as the data library I am using (Nhibernate, EF, etc..) supports IQueryable.
I am not sure how to do a generic repository without IQueryable, but you might be able to use delegates/lambda functions to incorporate it.
Edit2: And just in case I didn't answer your question correctly, if you are asking if you are supposed to call your repository's Get() method from the service then yes, that is the correct DDD design as well. The reason is that the service layer is supposed to handle all your business logic, so it decides exactly how and what data to retrieve (for example, do you want it in alphabetical order, unordered, etc...). It also means that it can perform validation after loading if needed or validation before deleting and/or saving.
This means that the service layer doesn't care exactly how that data is stored and retrieved, it only decides what data is stored and retrieved. It then calls on the repository to handle the request correctly and retrieve/store the data in the way the service layer tells it to. Thus you have correct separation of concerns.
I need to make a web application and I want to use MVC. However, my Model can't be one of the standard Models -- the data is not stored in a database but instead in an external application accessible only via a API. Since this is the first MVC application I've implemented I'm relying on examples to understand how to go about it. I can't find any examples of a non-DB based Model. An example of a custom Model would be fine too. Can anyone point me to such a beast? Maybe MVC is just to new and none exist.
It seems like I might be able to get away with the DataSet Model, however I've not seen any examples of how to use this object. I expect an example of DataSet could help me also. (Maybe it is the same thing?)
Please note: I've seen countless examples of custom bindings. This is NOT what I want. I need an example of a custom Model which is not tied to a specific database/table.
UPDATE
I found a good example from MS located here:
http://msdn.microsoft.com/en-us/library/dd405231.aspx
While this is the "answer" to my question, I don't really like it because it ties me to MS's view of the world. #Aaronaught, #jeroenh, and #tvanfosson give much better answers from a meta perspective of moving my understanding (and yours?) forward with respect to using MVC.
I'm giving the check to #Aaronaught because he actually has example code (which I asked for.) Thanks all and feel free to add even better answers if you have one.
In most cases it shouldn't matter what the backing source is for the actual application data; the model should be exactly the same. In fact, one of the main reasons for using something like a repository is so that you can easily change the underlying storage.
For example, I have an MVC app that uses a lot of web services - rarely does it have access to a local database, except for simple things like authentication and user profiles. A typical model class might look like this:
[DataContract(Namespace = "http://services.acme.com")]
public class Customer
{
[DataMember(Name = "CustomerID")]
public Guid ID { get; set; }
[DataMember(Name = "CustomerName")]
public string Name { get; set; }
}
Then I will have a repository interface that looks like this:
public interface ICustomerRepository
{
Customer GetCustomerByID(Guid id);
IList<Customer> List();
}
The "API" is all encapsulated within the concrete repository:
public class AcmeWSCustomerRepository : ICustomerRepository, IDisposable
{
private Acme.Services.CrmServiceSoapClient client;
public AcmeWSCustomerRepository()
: this(new Acme.Services.CrmServiceSoapClient())
public AcmeWSCustomerRepository(Acme.Services.CrmServiceSoapClient client)
{
if (client == null)
throw new ArgumentNullException("client");
this.client = client;
}
public void Dispose()
{
client.SafeClose(); // Extension method to close WCF proxies
}
public Customer GetCustomerByID(Guid id)
{
return client.GetCustomerByID(id);
}
public IList<Customer> List()
{
return client.GetAllCustomers();
}
}
Then I'll also probably have a local testing repository with just a few customers that reads from something like an XML file:
public class LocalCustomerRepository : ICustomerRepository, IDisposable
{
private XDocument doc;
public LocalCustomerRepository(string fileName)
{
doc = XDocument.Load(fileName);
}
public void Dispose()
{
}
public Customer GetCustomerByID(Guid id)
{
return
(from c in doc.Descendants("Customer")
select new Customer(c.Element("ID").Value, c.Element("Name").Value))
.FirstOrDefault();
}
// etc.
}
The point I'm trying to make here is, well, this isn't tied to any particular database. One possible source in this case is a WCF service; another is a file on disk. Neither one necessarily has a compatible "model". In this case I've assumed that the WCF service exposes a model that I can map to directly with DataContract attributes, but the Linq-to-XML version is pure API; there is no model, it's all custom mapping.
A really good domain model should actually be completely independent of the true data source. I'm always a bit skeptical when people tell me that a Linq to SQL or Entity Framework model is good enough to use throughout the entire application/site. Very often these simply don't match the "human" model and simply creating a bunch of ViewModel classes isn't necessarily the answer.
In a sense, it's actually better if you're not handed an existing relational model. It forces you to really think about the best domain model for your application, and not necessarily the easiest one to map to some database. So if you don't already have a model from a database - build one! Just use POCO classes and decorate with attributes if necessary, then create repositories or services that map this domain model to/from the API.
I think what you are looking for is really a non-DB service layer. Models, typically, are relatively simple containers for data, though they may also contain business logic. It really sounds like what you have is a service to communicate with and need a layer to mediate between the service and your application, producing the appropriate model classes from the data returned by the service.
This tutorial may be helpful, but you'd need to replace the repository with your class that interacts with the service (instead of the DB).
There is no fixed prescription of what a "Model" in MVC should be, just that it should contain the data that needs to be shown on screen, and probably also manipulated.
In a well-designed MVC application, data access is abstracted away somehow anyway, typically using some form of the Repository pattern: you define an abstraction layer (say, an IRepository interface) that defines the contract needed to get and persist data. The actual implementation will usually call a database, but in your case should call your 'service API'.
Here is an example of an MVC application that calls out to a WCF service.