I have several product tables in my database:
ProductTypes
ProductCategories
ProductCategoryItems
ProductInventory
The way I see it now, I can make IProduct which would have methods such as:
FindAllTypes()
FindAllCategories(int typeId)
FindAllItems(int categoryId)
Or, I can separate each to mimic the table structure: IProductType, IProductCategory, etc.
Is there a reason to go with one over another?
The idea of repositories is to delegate each one with responsibility for a single entity. In this case making a repository for each entity is recommended. You can go for the big repository one as well, but is not the best solution. In the end you'll get a HUGE class with lots of methods and really tight coupled. Also difficult to give maintenance to.
I don't think having a huge repository is really a good idea, then you'd basically have a data access god class that does everything.
I like to have a base Repository<T> which does common operations such as GetById and GetAll. I normally have all my repositories inherit this base class to get the common methods for free, so I don't have to keep rewriting the same code.
In my opinion it very much depends on the business domain model, it's very important to determine what are your main business entities. Not necessarily every table in the DB is directly mapped to a business entity. Tables are just representations of your one or many entities in a normalized way for relational databases.
Try to picture your domain model beyond the restrictions of normalized relational databases, is there really more than one business concept? Repositories should be constructed around solid, whole, first-class business entities.
My advice would be to have an IProductRepository with the necessary methods to implement CRUD operations and grow it as needed. You don't want to get too ambitious interfaces beacuse you may not need most of it, and it could be a burden. The important thing about interfaces is to decouple your code from the persistence schema, so you can latter offer the flexibility to switch between them.
Maybe in the future the business will need to evolve to a more detailed representation of -for instance- the product's providers, and in that moment you'll use your good judgement to decide wether that represents an important business entity worthy of a dedicated repository or not.
Hope this helps.
I disagree with the others (edit: except with Isaac). The small repositories are a facade (not the pattern).
If the entity types are coupled (have navigation properties to each other) then they are not really separatable.
Modifying one entity type and committing the changes may commit change to others.
Also, you can not create any small repository above the same unit of work,
since the ORM only has a limited amount of entities mapped to the database.
Divide your model into separatable domains and create one specific unit of work for each domain.
On these unit of works create aggregate roots for each entity type that you may require immediate access to.
Each root should have specifically typed add, remove, getbykeys, query and etc methods.
The unit of work should have the commitchanges and alike methods on it.
Each of the roots is similar to the small repositories the others mentioned, however, the unit of work is the real medium sized repository (of which your model may have more than one type of).
Example:
// Create one of these
interface IUnitOfWork
{
void Commit();
}
// Create one of these
interface IEntitySet<TEntity> where TEntity : class
{
void Add(TEntity entity);
void Remove(TEntity entity);
TEntity Create<TSpecificEntity>() where TSpecificEntity : TEntity;
IQueryable<TEntity> Query();
}
// Create one of these per entity type
interace IEntitySetOfTEntity1 : IEntitySet<Entity1>
{
TEntity1 GetByKeys(int key1);
}
interace IEntitySetOfTEntity2 : IEntitySet<Entity2>
{
TEntity1 GetByKeys(short key1, short key2);
}
// Create one of these per separatable domain
interface IDomain1UnitOfWork : IUnitOfWork
{
IEntitySetOfTEntity1 Entity1s
{
get;
}
IEntitySetOfTEntity2 Entity2s
{
get;
}
}
All these interfaces and their implementations can be auto-generated.
These interfaces and their implementations are very light weight and by no means are any of them "a HUGE class with lots of methods". Since they can be auto-generated, maintenance is easy.
Specific functionalities can be added to the interfaces IDomain1UnitOfWork, IEntitySetOfTEntity1 and alike by using:
a. extension methods
b. partial interfaces and classes (less recommended, since this results in a less clean DAL)
The IEntitySetOfTEntity1 like interfaces can be disgarded if you use extension methods to add the GetByKeys() methods to IEntitySet<Entity1>.
Related
I'm using elastic search with my asp.net core web api. I don't quite get where the line is drawn when it comes to repository responsibility.
Here is how I have defined my implementations:
public SearchRespository: ISearchRespository<Product>
{
private ElasticClient _client
public async Task<ISearchResponse<Product>> SearchAsync(ISearchRequest request)
{
var response = _client.SearchAsync<Product>(request);
return await products;
}
. . . // others
}
In my controller:
public SearchController : Controller
{
private ISearchRespository _repo;
public SearchController(ISearchRespository repo)
{
_repo = repo;
}
public async Task<IActionResult> Search()
{
// build my search request from Request.Query
var response = await _client.SearchAsync(request);
var model = new SearchModel
{
Products = response.Documents;
Aggregations = response.Aggregations;
}
return Ok(model)
}
As it stands the repo is passing the elastic response as is. My question is have I drawn my line right? what if I just move _client to my controller or move building request and constructing model to _repo? how do you guys get your repository right?
The fact that you use Elastic Search should be an implementation detail that especially the controller shouldn't know about, so you are absolutely right in abstracting this away from the controller. I often look at the SOLID principles to get a sense whether I'm on the right track or not. If we look at the Dependency Inversion Principle, you'll see that it guides us towards a style that is also known as Ports and Adapters, which basically means that the use of an external tool is abstracted away (the port), and on the boundary of the application you implement an Adapter that connects to that third party.
So from the sense of the Dependency Inversion Principle, you're on the right track.
There is however a lot of misunderstanding of what Martin Fowler's Repository Pattern is trying to solve. The definition is as follows:
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
Important to note here is that a repository is intended to be used by the domain layer.
There is however a lot of misuse of the repository pattern, because many developers start to use it as a grouping structure for queries. The repository is -as I see it- not intended for all queries in the system; but only for queries that are the domain needs. These queries support the domain in making decisions for the mutations on the system.
Most queries that your system requires however are not this kind of query. Your code is a good example, since in this case you skip the domain completely and only do a read operation.
This is something that is not suited for the repository. We can verify this by comparing it with the SOLID principles again.
Let's say we have the following repository interface:
public interface IUserRepository
{
User[] FindUsersBySearchText(string searchText, bool includeInactiveUsers);
User[] GetUsersByRoles(string[] roles);
UserInfo[] GetHighUsageUsers(int reqsPerDayThreshold);
// More methods here
}
This is a typical repository abstraction that you'll see developers write. Such abstraction is problematic from perspective of the SOLID principles, because:
The Interface Segregation Principle is violated, because the interfaces are wide (have many methods) and consumers of those interfaces are forced to depend on methods that they don’t use.
The Single Responsibility Principle is violated, because the methods in the repository implementation are not highly cohesive. The only thing that relates those methods is the fact that they belong to the same concept or entity.
The design violates the Open/Closed Principle, because almost every time a query is added to the system, an existing interface and its implementations need to be changed. Every interface has at least two implementations: one real implementation and one test implementation.
A design like this also causes a lot of pain down the road, because it becomes hard to apply cross-cutting concerns (like security, auditing, logging, caching, etc) down the line.
So this is not something the Repository pattern is intended to solve; such design is just a big SOLID violation.
The solution here is to model queries separately in your system and not use a repository at all. There are many articles written about this, and you can read my take on this here.
If I look at your design, it actually has some resemblance with the design I'm promoting here, since you seem to have a generic query method that can handle many type of queries. The query message (your ISearchRequest) seems however specific to Elastic Search. This is something you should strive to prevent, as the Dependency Inversion Principle states.
I've seen various blog posts (and much conflicting advice) about the repository pattern, and so I'll start by saying that the code below is probably not following the repository pattern in many people's opinion. However, it's a common-enough implementation, and whether it adheres to Fowler's original definition or not, I'm still interested in understanding more about how this implementation is used in practice.
Suppose I have a project where data access is abstracted via an interface such as the one below, which provides basic CRUD operations.
public interface IGenericRepository<T>
{
void Add(T entity);
void Remove(T entity);
void Update(T entity);
IEnumerable<T> Fetch(Expression<Func<T,bool>> where);
}
Further suppose that I have a service layer built atop that, for example:
public class FooService
{
private IGenericRepository<Foo> _fooRespository;
...
public IEnumerable<Foo> GetBrightlyColoredFoos()
{
return _fooRepository.Fetch(f => f.Color == "pink" || f.Color == "yellow");
}
}
Now suppose that I now need to know how many brightly colored Foos there are, without actually wanting to enumerate them. Ideally, I want to implement a CountBrightlyColoredFoos() method in my service, but the repository implementation gives me no way to achieve that other than by fetching them all and counting them - which is potentially very inefficient.
I could extend the repository to add a Count() method, but what about other aggregate functions that I might need, such as Min() or Max(), or Sum(), or... you get the idea.
Likewise, what if I wanted to get a list of the distinct Foo colors (SELECT DISTINCT). Again, the simple repository provides no way to do that sort of thing either.
Keeping the repository simple to make it easy to test/mock is very laudable, but how do you then address these requirements? Surely there are only two ways to go - a more complex repository, or a "back-door" for the service layer to use that bypasses the repository (and thus defeats its purpose).
I would say you need to change your design. What you want to do is have one "main" generic repository that has your basic CRUD, but also smaller repositories for each entity. You will then just have to draw a line on where to place certain operations (like sum, count, max, etc.) Most likely not all your entities are going to have to get counted, summed, etc. and most of the time you won't be able to add a generic version that applies to all entities for aggregate functions.
Base Repository:
public abstract class BaseRep<T> : IBaseRep<T> where T : class
{
//basic CRUD
}
Foo Repository:
public class FooRep : BaseRep<Foo>, IFooRep
{
//foo specific functions
}
would anybody interpret it into simple words as i'm newbie to MVC and can't understand this clearly.
A DbContext instance represents a combination of the Unit Of Work and
Repository patterns such that it can be used to query from a database
and group together changes that will then be written back to the store
as a unit. DbContext is conceptually similar to ObjectContext.
Source: http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v=vs.113).aspx
Unit of work and Repository are patterns for dealing with data(irrespective of if it is a database or any other storage(may be List<T> objects even)) and usually implemented while dealing with data from a database.
It only means that Entity framework internally has these two patterns implemented. To understand it better, just google for Repository Patterns and Unit of work pattern which usually go hand in hand.
If you still do not get the meaning, don't worry - until you know how to work with Entity Framework(Code First is extremely easy to understand, once you understand Linq) the understanding of pattern is not important. Refer back to the same article once you have more experience with the patterns of dealing with data. You only require a little more experience to appreciate them.
Examples of these two patterns are better described by the two interfaces:
interface IHomesRepository {
List<Home> GetAllHomes();
Home GetHomeById(int id);
void AddHome(Home home);
void UpdateHome(int id, Home home);
void DeleteHome(Home home);
}
interface IUnitOfWork : IDisposable{
IHomesRepository repository {get;}
// more repositories, if required
void Commit();
}
this is a good example to understand the unit of work and the repository pattern, i suggest you to read it until the end :
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
I have a class A that depends on 10 other classes. According to Dependency Injection pattern, i should pass all dependencies of A by its constructor.
So lets assume this constructor (of course this is not a working or real code, since I am not allowed to post the real code here)
public ClassA(ClassB b, ClassC c, ClassD d, ClassE e, ClassF f, ClassG g, ClassH h, ClassI i) {
this.b = b;
this.c = c;
this.d = d;
this.e = e;
this.f = f;
this.g = g;
this.h = h;
this.i = i;
}
I have read on Martin Fowler's book about refactoring that having a method with a lot of parameters is a code smell and should not happen.
My question is: is this OK when we are talking about DI? Is there a better way of inject dependencies without breaking Martin Fowler's rules?
I know I could pass the dependencies through properties, but that may cause errors since no one is really sure what should be pass in order that the class works.
EDIT
Thanks for all your answers. I will try now to demonstrate some of class A dependencies:
1 - A class to access a DB
2 - Another class to access another DB (yes, i need to perform operations on two databases)
3 - A class to send error notifications by email
4 - A class to load configurations
5 - A class that will act as timer for some operations (maybe this one can be avoided)
6 - A class with business logic
There any many others that i am trying to get rid of, but those are really necessary and I dont see any ways of avoiding them.
EDIT
After some refactoring now i have 7 dependencies (down from 10). But I have 4 DAO objects:
CustomerDAO
ProcessDAO
ProductsDAO
CatalogDAO
Is it correct do create another class called MyProjectDAO and inject those DAOS onto it? This way I will have only one DAO class that aggregates all DAO objects of my project. I dont think this is a good idea because it violates the Single Responsibility Principle. Am I right?
In my experience:
Try to design your class so it needs fewer dependencies. If it needs that many, it may have too many responsibilities.
If you're really convinced that your class design is appropriate, consider whether it may make sense for some of those dependencies to be joined together (e.g. via an adapter which takes responsibility for one "big" operation your class needs by delegating to a few of the dependencies). You can then depend on the adapter instead of the "smaller" dependencies.
If every other bit really makes sense, just swallow the smell of having a lot of parameters. It happens sometimes.
Can you justify (to yourself) why the class depends on 10 other classes? Are there member variables you use to tie together a subset of those classes? If so, that indicates that this class should be broken up so that the extracted class would depend on the subset and the variables that tie such state together goes in the extracted class. With 10 dependencies, it's possible that this class has simply grown too large and needs to have its internals broken up anyway.
A note regarding your final sentence: such order dependency can also be a code smell, so it's probably good not to expose it in your interface. In fact, consider whether or not the order requirements are because operations need to be carried out in a specific order (it is the complexity of the algorithm or protocol), or because you've designed your classes to be inter-dependent. If the complexity is due to your design, refactor to eliminate the ordered dependency where possible.
If you cannot refactor (the complexities are all essential and you just have a terrible coordination problem on your hands), then you can abstract the ugliness and keep users of this class shielded (builder, factory, injector, etc).
Edit: Now that I have thought about it, I am not convinced that essential complexities of your algorithm or protocol cannot be abstracted a bit (though that might be the case). Depending on your specific problem, similarities in the manipulations of those dependent classes might either be better solved with the Strategy pattern or the Observer pattern (event listeners). You might have to wrap these classes in classes that adapt them to slightly different interfaces than what they currently expose. You'd have to evaluate the tradeoff of having the code in this monster class become more readable (yay) at the expense of up to 10 more classes in your project (boo).
I'd also like to make an addendum to abstracting the construction of this class. It seems important that any class that depends on this class also use the Dependency Injection pattern. That way, if you do use a builder, factory, injector, etc. you don't accidentally rob yourself of some of the benefits of using the DI pattern (the most important in my mind is the ability to substitute mock objects for testing).
Edit 2 (based on your edit):
My first thought is "what, no logging dependency?" :)
Even knowing what the dependencies are, it's difficult to offer useful advice.
First: what are the responsibilities of everyone? Why does this class depend on controller code (the business logic) and on Model code (two different database access classes, with DAO classes)?
Depending both on DAOs and DB access classes is a code smell. What is the purpose of a DAO? What is the purpose of the DB classes? Are you trying to operate at multiple levels of abstraction?
One of the principles of OO is that data and behavior get bundled into little things called classes. Have you violated this when you created this business logic class distinct from the objects it manipulates distinct from the DAO distinct from this class? Related: Take a brief diversion into SOLID.
Second: A class to load configurations. Smells bad. Dependency Injection helps you identify dependencies and swap them out. Your monster class that depends on certain parameters. These parameters are grouped into this configuration class because...? What is the name of this configuration class? Is it DBparameters? if so, it belongs to the DB object(s), not to this class. Is it generic like Configurations? If so, you've got a mini dependency injector right there (granted, it is probably only injecting string or int values instead of composite data like classes, but why?). Awkward.
Third: The most important lesson I learned from Refactoring was that my code sucked. Not only did my code suck, but there was no single transformation to make it stop sucking. The best I could hope for was to make it suck less. Once I did that, I could make it suck less again. And again. Some design patterns are bad, but they exist to allow your sucky code to transition to less sucky code. So you take your globals and make them singletons. Then you eliminate your singletons. Don't get discouraged because you've just refactored to find that your code still sucks. It sucks less. So, your Configuration loading object may smell, but you might decide that it isn't the smelliest part of your code. In fact, you may find that the effort to "fix" it isn't worth it.
Yes - a method taking this many parameters should be considered a code smell. Is this method truly only doing one thing and one thing only?
If this is still true you can still lower the number of dependencies by looking at the relationships between the dependencies - are any of them closely related, could they be coupled into aggregate dependencies? E.g. you could refactor by creating a new class K that uses A, B and C internally (injected into class K by constructor, then using composition) - so the number of parameters to the method would be reduced by two.
Rinse and repeat until aggregating doesn't make sense anymore and/or you have a reasonable number of parameters.
Also see a related blog post: "Refactoring to Aggregate Services"
I'd also advise to redesign your application. In case it is not possible you can pass your IoC container as a constructor parameter. If you do not want to couple your code with a concrete implementation you can always abstract it. The code will look something like this.
public interface IAbstractContainer
{
T Resolve<T>();
}
public class ConcreteContainer: IAbstractContainer
{
private IContainer _container; // E.g. Autofac container
public ConcreteContainer(IContainer container)
{
_container = container;
{
public T Resolve<T>()
{
return _container.Resolve<T>();
}
}
public classA(IAbstractContainer container)
{
this.B = container.Resolve<ClassB>();
this.C = container.Resolve<ClassC>();
...
}
}
A ConcreteContainer instance is injected the usual way.
Asp.net-mvc, using nhibernate.
my vs.net layout is like:
/dao (1 class per entity for database work, using repository)
/model
/mappings
/factory (db factory that provides access to each entities Dao)
Now I need utility methods, not sure where to put them.
example:
CartItems.cs
CartIemsDao.cs
Now say I have a method like:
IList<CartItem> items = CartItemsDao.GetById(234)
Now I want to create a method that populates a Dictionary<int,CartItem> from a given IList<CartItem>. Should I create a CartItemManager.cs for this?
And what would a 'Service' type class be used for? e.g. CartService.cs
I believe someone said earlier a 'service' type class is to wrap multiple calls/logic for Dao's etc. Is that what it is?
There are several styles, you can definitely create a "helper" type that has all the static methods you need but this is not very discoverable from an API standpoint.
I would create these static methods on the data access objects themselves - this is much easier to discover. Of course nothing is stopping you from delegating the implementation of these static methods to some internal helper type.
Also as a side note: I don't personally care for the style of appending "DAO" or other similar identifiers to the names of types. The type is what it is so I would suggest that you leave off the "DAO" (but that has nothing to do with your question).
I would say that what you describe is a "Service", which I usually define loosely as [potentially] any operations I might want to make on entities that don't really fit into the entity itself (which practically by definition includes cross-aggregate operations).
To state it generally, you want transform a list of items into a dictionary of items using some function upon the item to derive the key.
With .Net generic typing, you could make a service for this so general it would fit best in a utility type of library that fits into the infrastructure layer where any other layer can utilize it.
public class CollectionToDictionaryMappingService {
IDictionary<TKey, TValue> Map<TKey, TValue>(ICollection <TValue> items, Func<TKey, TValue> keyAccessor)
{
var dictionary = new Dictionary<TKey, TValue>();
foreach (TValue val in items) {
dictionary.Add(keyAccessor(val), val);
}
return dictionary;
}
}
I propose to view it from a layered architecture point of view.
App layers
It depends how are you architecturing you app. I generally use two diferents layers for DAO and for Business/Logic.
In an information system logic layer generally replicates the methods of DAO, because the methods needed for implementing the use cases are get data / update data... much the same that the DAO layer. BUT I think it's important to separate them because you can add extra logic in the logic/business layer, things more complex (or composite) than the DAO.
List -> Dictionary case
I don't know if you need that method for business logic. If it's the case maybe the method can be private to some business class that uses it. Or it can be a public method of a protected helper class in the business layer.
If it's not the case I'd publish it in the business layer anyway.
BUT, if I follow the layered point of view... The service layer should provide methods for implementing the use cases. It is: it should provide the data structures needed. in this case: it should provide the dictionary.
So:
the convert method should be private to the business layer
or
be a generic conversion method like the proposed by qstarin