Domain driven design - access modifiers for entities and enforcing validation - validation

I am very new to DDD and reading various discussions on validation (where to put it) on the stackoverflow as well as on the web. I do like the idea of keeping the validations outside the entities and validate them depending upon the context. In our project, we have an entity called MedicalRecord and there are various rules for when one can be created or can be saved. I want to create a service layer, let's say RecordService, that would do some check to make sure if a user can create a medical record before creating one. I also want to create MedicalRecordRepository that would save the medical record. What confuses me is the access modifies on my entity and repository classes. Since both will be public, how can I enforce the client of my application to use the service instead of just creating new medical record (with public constructor) and use the repository to save it? I am using c#. I know DDD is language independent but wondering if someone could provide some thoughts on this.
Thanks.

You must control record creation by making the c'tor non-public and allowing creation only through a factory:
public class MedicalRecord
{
internal MedicalRecord()
{
}
}
public static class MedicalRecordFactory
{
public static MedicalRecord Create(User onBehalfOf)
{
// do logic here
return new MedicalRecord();
}
}
For the internal keyword to be applicable, either both classes must be in the same assembly or the class assembly must allow the factory assembly access with the InternalsVisibleTo attribute.
Edit
If you need to be able to perform validation at any time, you additionally have to encapsulate validation logic in another class (here partially done via an extension method):
public static class MedicalRecordValidator
{
public static bool IsValid(this MedicalRecord medicalRecord, <context>)
{
return IsValid(<context>);
}
public static bool IsValidForCreation(User onBehalfOf)
{
return IsValid(null, onBehalfOf);
}
private static bool IsValid(<context> context, User user = null)
{
// do validation logic here
}
}
then, the factory could do this:
public static MedicalRecord Create(User onBehalfOf)
{
return IsValidForCreation(onBehalfOf) ? new MedicalRecord() : null;
}
and you could also always do this:
if (myMedicalRecord.IsValid(<context>))
{
// ....

Only use your repository to retrieve your entities; not to save them. Saving (persisting) your entities is the responsibility of your unit of work.
You let your service change one or more entities (for instance a MedicalRecord) and track the changes in a unit of work. Before committing the changes in your unit of work, you can validate all entities for validation needs across entities. Then you commit your unit of work (in a single transaction), which will persist all your changes, or none at all.
For clarity, your MedicalRecord should protect its own invariants; such that a client retrieving a MedicalRecord using a repository, calling some methods to modify it and then persisting it using a unit of work, should result in a "valid" system state. If there are situations where this is not the case, then it can be argued that it should not be possible to retrieve a MedicalRecord on its own - it is part of some larger concept.
For creation purposes, using a factory like #Thomas suggests below is a good approach, although I think I'd call it a service (because of the collaboration between entities) instead of a factory. What I like about Thomas' approach is that it does not allow a client to create a MedicalRecord without a User (or other contextual information), without tying the MedicalRecord tightly to the user.

Related

MVC: Should logic be placed in the Model or Service layer?

Recently I talked with a co-worker and had a conversation regarding Model View Controller paradigm. We were talking about proper organization of files and such and I mentioned that I thought that "skinny controllers and fat models" were the way to go. Meaning that the controller just calls the "fat models" methods which contain business logic:
public class CreditCard {
//instance vars
//constructor
//getters
//setters (if you want mutability)
public boolean makeCreditCardPayment(Cart cart) {
//implementation details...
}
}
My co-worker mentioned otherwise. He said that the models shouldn't really be "fat" and contain any other business logic. The model should just be a data-structure and contain zero methods (obviously if your are in Java you need setters and getters). Just like a C-style structure, obviously with data fields that have mutators and accessors:
public class CreditCard {
//instance vars
//constructor
//getters
//setters (if you want mutability)
}
public class PaymentService {
public boolean makeCreditCardPayment(CreditCard card, Cart cart) {
//implementation details...
}
public boolean makePayPalPayment(PayPal paypal, Cart cart){
//implementation details...
}
Or even have a PaymentService for each type of payment that implements an interface. So something like 'CreditCardPaymentService implements Payment' or 'PayPalPaymentService implmeents Payment'.
To me, using the service method way seems like we are just going back to procedural style programming.
Another example would be a 'Vehicle' object with a getSpeed method compared to a service which takes in a Vehicle object and returns the speed.
I have looked over other stackoverflow answers but they have differing answers. In one question, one of the users mentioned that the service layer is part of the models part of MVC. I am looking for other answers.
I've encountered many different philosophies claimed to fall under the MVC umbrella.
My position:
Models directly manage some kind of backing store, and should contain mutation and validation logic.
Controllers should look like a model to other controllers and views (making them composable), and contain any additional logic required to validate the mapping from the controller's interface to a model's interface.
Views just contain whatever state and logic they need to function; their purpose is to display data and collect input.
It looks like your PaymentService is trying to be more than one controller, so I'd go the separate CreditCardPaymentService and PayPalPaymentService route.

Where to put my queries - model vs. controller

I just switched from ActiveRecord/NHibernate to Dapper. Previously, I had all of my queries in my controllers. However, some properties which were convenient to implement on my models (such as summaries/sums/totals/averages), I could calculate by iterating over instance variables (collections) in my model.
To be specific, my Project has a notion of AppSessions, and I can calculate the total number of sessions, plus the average session length, by iterating over someProject.AppSessions.
Now that I'm in Dapper, this seems confused: my controller methods now make queries to the database via Dapper (which seems okay), but my model class also makes queries to the database via Dapper (which seems strange).
TLDR: Should the DB access go in my model, or controller, or both? It seems that both is not correct, and I would like to limit it to one "layer" so that changing DB access style later doesn't impact too much.
You should consider using a repository pattern:
With repositories, all of the database queries are encapsulated within a repository which is exposed through public interface, for example:
public interface IGenericRepository<T> where T : class
{
T Get(object id);
IQueryable<T> GetAll();
void Insert(T entity);
void Delete(T entity);
void Save(T entity);
}
Then you can inject a repository into a controller:
public class MyController
{
private readonly IGenericRepository<Foo> _fooRepository;
public MyController(IGenericRepository<Foo> fooRepository)
{
_fooRepository = fooRepository;
}
}
This keeps UI free of any DB dependencies and makes testing easier; from unit tests you can inject any mock that implements IRepository. This also allows the repository to implement and switch between technologies like Dapper or Entity Framework without any client changes and at any time.
The above example used a generic repository, but you don't have to; you can create a separate interface for each repository, e.g. IFooRepository.
There are many examples and many variations of how repository pattern can be implemented, so google some more to understand it. Here is one of my favorite articles re. layered architectures.
Another note: For small projects, it should be OK to put queries directly into controllers...
I can't speak for dapper personally, but I've always restricted my db access to models only except in very rare circumstances. That seems to make the most sense in my opinion.
A little more info: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
A model notifies its associated views and controllers when there has been a change in its state. This notification allows the views to produce updated output, and the controllers to change the available set of commands. A passive implementation of MVC omits these notifications, because the application does not require them or the software platform does not support them.
Basically, data access in models seems to be the standard.
I agree with #void-ray regarding the repository model. However, if you don't want to get into interfaces and dependency injection you could still separate out your data access layer and use static methods to return data from Dapper.
When I am using Dapper I typically have a Repository library that returns very small objects or lists that can then be mapped into a ViewModel and passed to the View (the mapping is done by StructureMap, but could be handled in the controller or another helper).

Using Ninject in a SOLID application architecture

I'm starting with MVC3 and want to use some flexible architecture, so I've read tens of blogs, a book (Pro ASP.NET MVC 3), read about SOLID principles and finally got to an application structure I like (or at least I think so, so far, because I haven't built anything on it yet):
In this structure:
Domain holds the POCO classes and defines the service interfaces
Services implements service interfaces and defines repositories interfaces
Data implements repositories interfaces
WebUI and Domain use Services
Services use Repositories
WebUI, Services and Data depend on Domain for POCO classes
The main reason for Domain using Services is to validate unique keys on the Validate methods of POCO (IValidatable) classes.
I'm starting to build a reference application with this structure but I have faced, so far, two problems:
I'm using a Data.Tests project with unit tests for the repositories, but haven't found a way to inject (using Ninject) a implementation of the service (in the constructor or otherwise) on the model, so the Validate method can call the CheckUniqueKey on the service.
I haven't found any reference about hooking up Ninject to a TEST project (lots of for the WebUI project).
What I'm trying to achive here is beeing able to switch from EF to something else like DAPPER, by just changing the DATA assembly.
UPDATE
Right now (as of 09-AUG-2011) Ninject is working but I think I'm missing something.
I have a CustomerRepository with two constructors:
public class CustomerRepository : BaseRepository<Customer>, ICustomerRepository
{
// The repository usually receives a DbContext
public CustomerRepository(RefAppContext context)
: base(context)
{
}
// If we don't receive a DbContext then we create the repository with a defaulte one
public CustomerRepository()
: base(RefApp.DbContext())
{
}
...
}
On the TestInitialize:
// These are for testing the Repository against a test database
[TestInitialize()]
public void TestInitialize()
{
// Context used for tests
this.context = new RefAppContext();
// This is just to make sure Ninject is working,
// would have used: repository = new CustomerRepository(context);
this.kernel = NinjectMVC3.CreateKernel();
this.kernel.Rebind<ICustomerRepository>().To<CustomerRepository>().WithConstructorArgument("context", context);
this.repository = kernel.Get<ICustomerRepository>();
}
On the Customer class:
public class Customer : IValidatableObject
{
...
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// I want to replace this with a "magic" call to ninject
CustomerRepository rep = new CustomerRepository();
Customer customer = rep.GetDupReferenceCustomer(this);
if (customer != null)
yield return new ValidationResult("Customer \"" + customer.Name + "\" has the same reference, can't duplicate", new [] { "Reference" });
}
...
}
What would be the best way to use Ninject in this scenario?
Any help will be highly appreciated.
ANSWER, SORT OF
I'll consider this question as aswered so far. I could get Ninject working, sort of, but it looks like achiving the Dependency Inversion Principle (DIP) of SOLID is going to take some more time.
In that respect, I had to lump together Domain, Services and Data, I'll create another question some other time and keep the project going the usual way for now.
Thanks everybody.
Unit testing should be done without Ninject. Just create an instance of the object under test and inject a mock for every dependency manually.
For Integration Tests you can use the kernel inclusive all bindings from the application bootstrapper and rebind everything you want to replace by a Mock. e.g. Replace the Session binding by one that uses an in memory data storage instead of a real database.

LINQ-to-XYZ polymorphism?

I have a situation where a client is requiring that we implement our data access code to use either an Oracle or SQL server database based on a runtime configuration settings. The production environment uses Oracle but both dev and QA are running against a SQL Server instance.
(I don't have any control over this or have any background on why this is the case other than Oracle is their BI platform and dev wants to work with SQL Server.)
Their request is to use LINQ-to-SQL / LINQ-to-Oracle for all data access. They will need to support the application and do not have the knowledge to jump into EF yet (their requirement) - although I believe the same problem exists if we use EF.
While I can implement LINQ to XYZ classes for both databases so that I can connect to both, they don't share a common interface (other than DataContext) so I really can't code against an interface and plug the actual implementation in at runtime.
Any ideas how I should approach this?
UPDATE
After writing this post, I did a little investigating into EF and it appears to me that this same problem exists if I use EF - which would be my long term goal.
Just a quick thought. Use MEF framework and plug your DAL layers to it. Then based on the environment(dev, production, QA) you can switch to the various DAL layers(Oracle, SQL etc.).
If you want to know about MEF , here is a quick intro.
Also sometime back I have seen a Generic Data Access Framework by Joydip Kanjilal. You can even have a look into that.
What you have to do is encapsulate the ORM datacontext in an interface of your creation, like IDataContext.
Then share this interface between all DALs and implement it. How you will plug it in is just your preference, using MEF as suggested or a IoC container.
For the sake of closure on this topic, here is what I ended up doing:
I implemented a combination of the Unit of Work and Repository patterns. The Unit of Work class is what consuming code works with and exposes all of the operations that can be performed on my root entities. There is one UoW per root entity. The UoW makes use of a repository class via an interface. The actual implementation of the repository is dependent on the data access technology being used.
So, for instance, if I have a customer entity and I need to support retrieving and updating each record, I would have something like:
public interface ICustomerManager
{
ICustomer GetCustomer(Guid customerId);
void SaveCustomer(ICustomer customer);
}
public class CustomerManager : ICustomerManager
{
public CustomerManager(ICustomerRepository repository)
{
Repository = repository;
}
public ICustomerRepository Repository { get; private set; }
public ICustomer GetCustomer(Guid customerId)
{
return Repository.SingleOrDefault(c => c.ID == customerId);
}
public void SaveCustomer(ICustomer customer)
{
Repository.Save(customer);
}
}
public interface ICustomerRepository : IQueryable<ICustomer>
{
void Save(ICustomer customer);
}
I'm using an Inversion of Control framework to inject the ICustomerRepository implementation into the CustomerManager class at runtime. The implementation class will be in a separate assembly that can be swapped out as the data access technology is changed. All we are concerned about is that the repository implements each method using the contract defined above.
As a side note, to do this with Linq-to-SQL, I simply created a LinqCustomerRepository class that implements ICustomerRepository and added a partial class for the generated Customer entity class that implements ICustomer. Then I can return the L2S entity from the repository as the implementation of the ICustomer interface for the UoW and calling code to work with and they'll be none the wiser that the entity originated from L2S code.

Extend linq-to-sql partial class to avoid writing a property?

I have a linq-to-sql class. I have a property "Password" for which I want to call the underlying ASP.NET Membership provider. Thus, I do not want this property written out directly but via my own code. I basically want to create a facade/proxy for this property such that I may use the underlying membership provider or a custom stored procedure.
I want to accomplish without modifying the LINQ-TO-SQL designer generated code, if at all possible.
It is possible. You can add your properties and methods to linq generated class using partial class mechanism. Linq generated classes are marked partial so you can add class members with:
public partial class YourLinqClass
{
// your methods and properties. refer linq properites and methods with "this."
// example:
public string Password
{
get
{
int id = this.UserId;
string password = // ... get password
return password;
}
set
{
// ...
}
}
}
You have to place the partial class in the same namespace as the rest of dbml.
The best option is to remove the property from the designer and write it in code, in the partial class, as described by PanJanek.
However, if you do it this way, you are pursuing a bad design. You're introducing a dependency into your entity class that breaks layer encapsulation. Entity classes shouldn't know about providers any more than they know about the DataContext that loads them. They aren't really meant to be anything more than containers for data going in and out of the database.
You should consider making a separate class that wraps the entity, the context, the username provider, and whatever other services you require, and in that class retrieve the username and do the required operations to your entity.
It looks like it might be possible to create a custom DataContext to handle this situation.
http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx
There are partial methods for the individual properties as, well and an OnValidate method.
In my case, I think the best solution is to throw an exception in the property changing method and add a public method for setting this individual property. This solution while not perfect will avoid touching the SQL generated code, where the property could be set to readonly or the setter removed.
Other suggestions welcome.

Resources