I'm thinking a bit about "best practice" regarding testability and the best way to define a particular action.
In the SportsStore application (from Pro ASP.NET MVC 4), for the AdminController, we have the following two methods in the AdminController.cs file:
IProductRepository
namespace SportsStore.Domain.Abstract {
public interface IProductRepository {
IQueryable<Product> Products { get; }
void SaveProduct(Product product); //Defined in EFProductRepository
void DeleteProduct(Product product); //Defined in EFProductRepository
}
}
AdminController:
private IProductRepository repository;
public ViewResult Edit(int productId) {
Product product = repository.Products.FirstOrDefault(p => p.ProductID == productId);
...
}
[HttpPost]
public ActionResult Delete(int productId) {
Product prod = repository.Products.FirstOrDefault(p => p.ProductID == productId);
...
}
As I noticed, we are basically doing the same bit of logic, that being, finding the productID. If productId changes at all, to something else, we need to change this in two spots. This can be tested, easily, though, since the controller itself is making the Linq call.
I was thinking that I could put this into the equivalent of the EFProducts (so the database implementation of the IProducts interface), but this creates a tie to a database state of some kind. I'd like to avoid this in my unit tests as it increases testing complexity a fair amount.
Is there a better place to put this FindOrDefault logic, rather than in the controller, yet keep a good amount of testability?
Edit1: Adding the definition for the repository, which points to an interface
The responses under my question discuss the possibilities. Both the book and #maess agree in keeping the logic for this particular part in the controller. The comments under my question are worth looking at, as both #SOfanatic and #Maess provided fantastic input.
Related
In my attempt to start learning about DDD, I began with a simple domain model that I will gradually build up over time. My domain in this instance is the usual order > order item in order to keep things simple and be able to add on later with invoices, etc. Here's what I have so far:
public class Order
{
private readonly IList<OrderItem> _orderItems;
public Guid Id { get; private set; }
public bool Completed { get; private set; }
public DateTime Created { get; private set; }
public IEnumerable<OrderItem> OrderItems
{
get { return _orderItems; }
}
public Order()
{
Id = new Guid();
Created = DateTime.UtcNow;
_orderItems = new List<OrderItem>();
}
public void AddOrderItem(int quantity, int unitCost)
{
var orderItem = new OrderItem(quantity, unitCost);
_orderItems.Add(orderItem);
}
public void CompleteOrder()
{
Completed = true;
}
}
public class OrderItem
{
public int Quantity { get; private set; }
public int UnitCost { get; private set; }
public OrderItem(int quantity, int unitCost)
{
Quantity = quantity;
UnitCost = unitCost;
}
}
I will eventually turn Quantity and UnitCost into value objects, but that isn't the important part here. As DDD preaches, we always want to protect our invariants, but I'm having a little trouble with one piece of that. From an Order, you can add a new OrderItem by calling the AddOrderItem() method and passing your quantity and unit cost.
My question now becomes what is to stop another coder from creating a new OrderItem with var orderItem = new OrderItem(1, 2)? The OrderItem constructor should probably have an Order order parameter since an OrderItem cannot exist without an Order, but again now that other coder could just call new OrderItem(new Order(), 1, 2)?
Am I missing something? Or is it just accepted that the team working on the model needs to understand the fundamentals of DDD?
Update
Thanks #theDmi, #guillaume31, #Matt as you all have provided some good points. I think it is pretty clear at this point that the repository's interface should be enough to make it clear that you can't do anything with an OrderItem created by itself. Setting the ctor for OrderItem to internal also helps to enforce this restriction as well, but it may not be needed. I plan to see what happens with or without the internal ctor. Ultimately, the reason I accepted #guillaume31's answer is the comment about the bidirectional relationships. That makes a lot of sense and I have encountered this issue in the past with EF for example, so I like the idea of keeping it unilateral as well.
"An OrderItem cannot exist without an Order" is not really an invariant. Well at least it's not an invariant in the Order aggregate. By definition, invariants only look at things that are inside one aggregate (or span across multiple ones), not things that wander around outside an aggregate.
The OrderItem constructor should probably have an Order order
parameter since an OrderItem cannot exist without an Order
I wouldn't model it that way, because
Bidirectional relationships between entities are not recommended. It can lead to synchronization problems (A points to B but B points to something else), it's better to have unidirectional relations if you can.
By doing that, your ultimate goal is to put a constraint on what's happening outside an Aggregate, which is not really the point of DDD, and, as other answers have shown, dispensable. All changes in a DDD system go through an Aggregate and a Repository.
When working with DDD, all attempts to change the state of the system run through a repository, because you need to retrieve the aggregate you want to work on first. So even if someone creates objects that make no sense outside of a certain entity, they will not be able to do anything useful with it.
Regarding this problem, DDD has even advantages over CRUD-based systems: It leads to a high discoverability. First, the repository interface tells you what you can load. Then you get an aggregate, which in turn offers operations that modify the aggregate in a meaningful way.
What would you guys recommend as being the best way to implement search in servicestack. For instance at the moment I have an advanced search form which in the backend simply builds up a linq query dynamically. If I wanted to expose the search feature using service stack what is the best way to go about it.
I have seen some people using the idea of creating a request property like [object].FirstnameStartsWith , [object].SurnameContains etc
I went with something like this
[Route("/things", "GET")]
public class ThingList
{
public string Term { get; set; }
public int Take { get; set; }
public int Skip { get; set; }
}
public partial class ThingService : Service
{
public object Get(ThingList req)
{
var query = this.Things // from somewhere
if(!string.IsNullOrEmpty(req.Term))
query = query.Where(x => x.Name.Contains(req.Term));
if(req.Skip > 0) query = query.Skip(req.Skip);
if(req.Take > 0) query = query.Take(req.Take);
return query.ToList();
}
}
There's no best way to design APIs for services, but your goals should be to be as descriptive and user-friendly as possible so clients can determine exactly what the service does by just looking at the request DTO.
Generally services should be cohesive and relevant for the use-case of the clients call context consuming them, e.g adding a new field/feature for that request should have the potential to be useful for existing clients already consuming that service.
Searching and Filtering a result-set is good example of this where every field/feature added is filtering the target result-set.
Other concerns I have when designing services is cache-ability, i.e. I separate long-term cacheable results from short-term non-cachable info.
I was reading about anemic domain model is a antipattern and I had some questions about.
I have a database where three clients uses and each one of them has diferrents business rules to insert a product into database.
So, if I use a rich domain model, my code will be something like this:
public class Product: IValidatableObject
{
public int Id;
public Client Client;
public int ClientId;
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (ClientId == 1)
DoValidationForClientOne();
else if (ClientId == 2)
DoValidationForClientTwo();
else if (ClientId == 3)
DoValidationForClientThree();
}
}
well, it's horrible, isn't?
Now if I have an anemic domain model I could simple create three services layer classes where each one of them would contain a validation for one especific client. Isn't it good?
My second argument is: if I have a desktop and a web application using the same rich domain model, how can I know when to throw a HttpException and when to throw some desktop exception? Wouldn't it better to separate it?
So, finally, why an anemic domain model is an anti pattern in a situation like this in my project?
An AnaemicDomainModel has its place: https://softwareengineering.stackexchange.com/questions/160782/are-factors-such-as-intellisense-support-and-strong-typing-enough-to-justify-the
Your domain model should not be throwing exceptions that are specific to a presentation platform. Let your presentation code sort that out. You should aim to make your domain model agnostic of its presentation.
As already stated - you showed just a DTO, not a domain entity.
In DDD, you would have some constant rules directly in Product entity and some number of ProductPolicies to encapsulate what can differ in handling products in defferent contexts. Horrible? No. Beautiful and powerful. But only if your domain is complex enough. If it's not - use an anemic model.
Your domain should not depend on anything. Should not know anything about web platform, desktop platform, ORM being used, DI container being used. So if you throw an exception, it should be a domain custom exception. Read about onion architecture or hexagonal architecure for more detailed explanation: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
I will recommend following:
Define IProductValidator interface, and provide 3 implementations as:
interface IProductValidator {
void validateProduct(Product product);
}
Change Client class, and add following methods to it
class Client {
void validateProduct(Product product) {
getProductValidator().validate(product);
}
IProductValidator getProductValidator() {
// this method returns validator, and it's better the method
// be abstract, and be implemented in sub-classes according
// to their type
}
}
And change the Product class to:
public class Product: IValidatableObject {
public int Id;
public Client client;
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
client.validate(this);
}
}
Now tou
I know that the Specification pattern describes how to use a hierarchy of classes implementing ISpecification<T> to evaluate if a candidate object of type T matches a certain specification (= satisfies a business rule).
My problem : the business rule I want to implement needs to evaluate several objects (for example, a Customer and a Contract).
My double question :
Are there typical adaptations of the Specification patterns to achieve this ? I can only think of removing the implementation of ISpecification<T> by my specification class, and taking as many parameters as I want in the isSatisfiedBy() method. But by doing this, I lose the ability to combine this specification with others.
Does this problem reveal a flaw in my design ? (i.e. what I need to evaluate using a Customer and a Contract should be evaluated on another object, like a Subscription, which could contain all the necessary info) ?
In that case (depending on what the specification precisely should do, I would use one of the objects as specification subject and the other(s) as parameter.
Example:
public class ShouldCreateEmailAccountSpecification : ISpecification<Customer>
{
public ShouldCreateEmailAccountSpecification(Contract selectedContract)
{
SelectedContract = selectedContract;
}
public Contract SelectedContract { get; private set; }
public bool IsSatisfiedBy(Customer subject)
{
return false;
}
}
Your problem is that your specification interface is using a generic type parameter, which prevents it from being used for combining evaluation logic across different specializations (Customer,Contract) because ISpecification<Customer> is in fact a different interface than ISpecification<Contract>. You could use Jeff's approach above, which gets rid of the type parameter and passes everything in as a base type (Object). Depending on what language you are using, you may also be able to pull things up a level and combine specifications with boolean logic using delegates. C# Example (not particularly useful as written, but might give you some ideas for a framework):
ISpecification<Customer> cust_spec = /*...*/
ISpecification<Contract> contract_spec = /*... */
bool result = EvalWithAnd( () => cust_spec.IsSatisfiedBy(customer), () => contract_spec.IsSatisfiedBy( contract ) );
public void EvalWithAnd( params Func<bool>[] specs )
{
foreach( var spec in specs )
{
if ( !spec() )
return false; /* If any return false, we can short-circuit */
}
return true; /* all delegates returned true */
}
Paco's solution of treating one object as the subject and one as a parameter using constructor injection can work sometimes but if both objects are constructed after the specification object, it makes things quite difficult.
One solution to this problem is to use a parameter object as in this refactoring suggestion: http://sourcemaking.com/refactoring/introduce-parameter-object.
The basic idea is that if you feel that both Customer and Contract are parameters that represent a related concept, then you just create another parameter object that contains both of them.
public class ParameterObject
{
public Customer Customer { get; set; }
public Contract Contract { get; set; }
}
Then your generic specification becomes for that type:
public class SomeSpecification : ISpecification<ParameterObject>
{
public bool IsSatisfiedBy(ParameterObject candidate)
{
return false;
}
}
I don't know if I understood your question.
If you are using the same specification for both Customer and Contract, this means that you can send the same messages to both of them. This could be solved by making them both to implement an interface, and use this interface as the T type. I don't know if this makes sense in your domain.
Sorry if this is not an answer to your question.
I've been trying to come up with a way to write generic repositories that work against various data stores:
public interface IRepository
{
IQueryable<T> GetAll<T>();
void Save<T>(T item);
void Delete<T>(T item);
}
public class MemoryRepository : IRepository {...}
public class SqlRepository : IRepository {...}
I'd like to work against the same POCO domain classes in each. I'm also considering a similar approach, where each domain class has it's own repository:
public interface IRepository<T>
{
IQueryable<T> GetAll();
void Save(T item);
void Delete(T item);
}
public class MemoryCustomerRepository : IRepository {...}
public class SqlCustomerRepository : IRepository {...}
My questions: 1)Is the first approach even feasible? 2)Is there any advantage to the second approach.
The first approach is feasible, I have done something similar in the past when I wrote my own mapping framework that targeted RDBMS and XmlWriter/XmlReader. You can use this sort of approach to ease unit testing, though I think now we have superior OSS tools for doing just that.
The second approach is what I currently use now with IBATIS.NET mappers. Every mapper has an interface and every mapper [could] provide your basic CRUD operations. The advantage is each mapper for a domain class also has specific functions (such as SelectByLastName or DeleteFromParent) that are expressed by an interface and defined in the concrete mapper. Because of this there's no need for me to implement separate repositories as you're suggesting - our concrete mappers target the database. To perform unit tests I use StructureMap and Moq to create in-memory repositories that operate as your Memory*Repository does. Its less classes to implement and manage and less work overall for a very testable approach. For data shared across unit tests I use a builder pattern for each domain class which has WithXXX methods and AsSomeProfile methods (the AsSomeProfile just returns a builder instance with preconfigured test data).
Here's an example of what I usually end up with in my unit tests:
// Moq mocking the concrete PersonMapper through the IPersonMapper interface
var personMock = new Mock<IPersonMapper>(MockBehavior.Strict);
personMock.Expect(pm => pm.Select(It.IsAny<int>())).Returns(
new PersonBuilder().AsMike().Build()
);
// StructureMap's ObjectFactory
ObjectFactory.Inject(personMock.Object);
// now anywhere in my actual code where an IPersonMapper instance is requested from
// ObjectFactory, Moq will satisfy the requirement and return a Person instance
// set with the PersonBuilder's Mike profile unit test data
Actually there is a general consensus now that Domain repositories should not be generic. Your repository should express what you can do when persisting or retrieving your entities.
Some repositories are readonly, some are insert only (no update, no delete), some have only specific lookups...
Using a GetAll return IQueryable, your query logic will leak into your code, possibly to the application layer.
But it's still interesting to use the kind of interface you provide to encapsulate Linq Table<T> objects so that you can replace it with an in memory implementation for test purpose.
So I suggest, to call it ITable<T>, give it the same interface that the linq Table<T> object, and use it inside your specific domain repositories (not instead of).
You can then use you specific repositories in memory by using a in memory ITable<T> implementation.
The simplest way to implement ITable<T> in memory is to use a List<T> and get a IQueryable<T> interface using the .AsQueryable() extension method.
public class InMemoryTable<T> : ITable<T>
{
private List<T> list;
private IQueryable<T> queryable;
public InMemoryTable<T>(List<T> list)
{
this.list = list;
this.queryable = list.AsQueryable();
}
public void Add(T entity) { list.Add(entity); }
public void Remove(T entity) { list.Remove(entity); }
public IEnumerator<T> GetEnumerator() { return list.GetEnumerator(); }
public Type ElementType { get { return queryable.ElementType; } }
public IQueryProvider Provider { get { return queryable.Provider; } }
...
}
You can work in isolation of the database for testing, but with true specific repositories that give more domain insight.
This is a bit late... but take a look at the IRepository implementation at CommonLibrary.NET on codeplex. It's got a pretty good feature set.
Regarding your problem, I see a lot of people using methods like GetAllProducts(), GetAllEmployees()
in their repository implementation. This is redundant and doesn't allow your repository to be generic.
All you need is GetAll() or All(). The solution provided above does solve the naming problem though.
This is taken from CommonLibrary.NET documentation online:
0.9.4 Beta 2 has a powerful Repository implementation.
* Supports all CRUD methods ( Create, Retrieve, Update, Delete )
* Supports aggregate methods Min, Max, Sum, Avg, Count
* Supports Find methods using ICriteria<T>
* Supports Distinct, and GroupBy
* Supports interface IRepository<T> so you can use an In-Memory table for unit-testing
* Supports versioning of your entities
* Supports paging, eg. Get(page, pageSize)
* Supports audit fields ( CreateUser, CreatedDate, UpdateDate etc )
* Supports the use of Mapper<T> so you can map any table record to some entity
* Supports creating entities only if it isn't there already, by checking for field values.