How to access EF class properties from Service Layer - c#

I have an ASP.NET MVC3 in C# and Razor. The architecture of the application is divided in Data Access Layer (EF classes + Repository), Service Layer, Controller, ViewModels and View.
From my Service Layer ProductServices I call the method GetAllProducts exposed by my Repository ProductRepository , which has the following signature:
IQueryable<Products> GetAllProducts()
Therefore within ProductServices I call (productRepository is an instance of ProductRepository):
var products = productRepository.GetAllProducts();
that populates the variable products. Now I would like to access the name of the product ProductName from productServices. If I use this instruction:
var productNames = products.Select(m => m.ProductName).ToList();
I am creating coupling between ServiceLayer and the EF (bypassing the repository). That means I must add to ProductRepository a method with signature:
IQueryable<string> GetAllProductsName()
However, since I need other product information in my application, shall I create one method in productRepository for each field of the Product class? Is my reasoning correct? Thanks

Theres two schools of thought around this,
A repository explicitly defines the way you interact with the database and should be tightly controlled. Therefore methods on the repository should provide enumerated data
The repository breaks the strong coupling to a specific datasource type but does not need to provide detailed and enumerated datasets.
Personally i subscribe to the second, heres why:
my feeling is that when you get overly explicit within the repository it turns into business logic rather than a decoupling mechanism. I don't really like this as it means that you become more tightly linked to the repository implementation.
I also think that in some cases the repository isnt the right place to enumerate the data, for example I believe paging and sorting is a UI concern, however for performance you want queries to only relate to the current page/sort. this means you either need to let the UI contribute to the query compilation or the repository needs to understand paging and sorting.
Having said that providing un-enumerated datasources does open you up for issues later down the track, and even if you do provide them its very important to enumerate the set as soon as possible.
If you're interested heres my take on the repositories: http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html , all the code is also on github

You have all information in your productServices because you load all information from your Repository with the method productRepository.GetAllProducts(). If you need more information from an other entity then you need to extend your productServices with a new Service.
However, since I need other product information in my application,
shall I create one method in productRepository for each field of the
Product class? Is my reasoning correct? Thanks
In this situation normally I create Extensions method's for the service and not in the repository. The Repository have normally a CRUD Setup and nothing more.

Related

C# Class Structure to Ensure Certain Filters Are Always Applied

So I'm currently working on a project with a team, and my team and I have come across a certain design scenario that we are trying to come up with a solution for.
Background Info of Current Project Implementation:
This problem involves three main projects in our solution: Repository, Models, and Services project. In case it isn't obvious, the purpose of each project is as follows. The Models project contains models of all the data we store in our database. The Repository project has one main database access class that uses generics to interact with different tables depending on the model passed in. Lastly the Services project contains classes that interface data between the front-end and repository, and in general each service class maps 1-to-1 to a model class. As one would expect, the build dependencies are: Repository relies on Models, and Services relies on both projects.
The Issue:
The current issue we are encountering is that we need a way to ensure that if a developer attempts to query or interact with a specific type of object (Call it ModelA), then we want to ensure that a specific set of filters is always included by default (and these filters are partially based on if a particular user has permissions to view certain objects in a list). A developer should be able to override this filter.
What we want to avoid doing is having an if clause in the repository classes that says "if you're updating this model type, add these filters".
Solutions we have thought of / considered:
One solution we are currently considering is having a function in ServiceA (the service corresponding to ModelA) that appends these filters to a given query, and then to make it so that if anyone requests for the db context of a model, they must pass in a function that manipulates filtering in some fashion (in other words, if they want to interact with ModelA, they would pass in the filter function from ServiceA). The issue with this solution is that a developer needs to always be aware that if they ever interact with ModelA, they must pass in the function from ServiceA. Also, because we don't want every model to enforce certain filter options, we would likely want this to be an optional parameter, which might then cause issues where developers simply forget to include this function when interacting with ModelA.
Another solution we considered is to have an attribute (let's call it DefaultFilterAttribute) on ModelA that stores a class type that should implement a particular interface (called IFilterProvider). ServiceA would implement this interface, and ModelA's attribute would be given ServiceA as a type. Then the repository methods can check if the entity passed in has a DefaultFilterAttribute on it, and then simply call the method implemented by the class attached to the attribute. Unfortunately, as some of you might have noticed, the way our project dependencies are currently set up, we can't really implement a solution like this.
So I'm wondering if there is a clean solution to this problem, or if potentially we are thinking about the problem and/or design pattern incorrectly, and should be taking a completely different approach.
I think you're making this unnecessarily complex. What you're describing is pretty much the entire purpose of a service layer. Presumably, you'd have something like GetModelAList (that's actually a pretty bad method for a service, but just for illustration). The logic of applying certain filters automatically, then, is encapsulated in that method. The application doesn't know or care how that data is retrieved; it just knows if it wants a list of ModelA instances, it calls that method.
If you then want a way to not apply those filters, you can provide another method such as GetModelAListUnfiltered, or pass a boolean or something in to the original method that determines whether filters are automatically applied. Really you can handle this however you want, but the point is that it's all encapsulated in your service.
Lastly, you haven't specified exactly what your repository is doing, but a repository should be extremely simple, really just returning sets of all objects. Logic like what you're talking about belongs in a service layer. However, even that only applies if you're doing direct database access using something like Dapper or ADO.NET. If you're using a full-fledged ORM like Entity Framework, throw away your repository layer entirely. Yes, you heard me correctly: throw it away completely. A repository wrapped around an ORM is a useless abstraction, only serving to add more code that needs to be maintained and tested for no good reason whatsoever. The benefits some level of abstraction gives you is already provided by the service layer.

Does adding extension methods to ViewModel Maintain ViewModel Rules?

There are certain methods in my ViewModel that access a database connection. I know this is not correct since the ViewModel shouldn't be responsible for connecting to a database.
So as a solution, I moved some of my methods to another class as extention methods. I.e.
Public static void (this MainViewModel viewModel){
viewModel.Textbox = "hello";
viewModel.Tables = GetDatabaseConnectionAndReturnTables();
//...//
}
Is this really a way to get database connection functionality out of the viewmodel? This is the only solution I could come up with.
Thanks,
Luke
Is this really a way to get database connection functionality out of
the viewmodel?
Short answer: no.
Not that long answer: extension methods are meant to add methods to types when source code isn't available, you can't derive a class or you want to add them to a struct (struct aren't inheritable...).
Actually you're adding methods to your view models as if they were added as direct class members. Either if you implement them as view model instance members or using extension methods, you're implementing methods in the view model.
If you want to effectively abstract data from view models you should check some design patterns like:
Repository.
Unit of Work.
Domain model.
Service layer.
Inversion of control.
DTO.
It would be hard to provide you more guidance about how to achieve a true separation of concerns in a Q&A format (I would need to write a book here), but I would start learning more about these design patterns.
Also, I would take a look at what's domain-driven design.
Going this route could get pretty wacky. If there was a choice between extension methods and nesting the functions within the view-model, then the latter would be preferred.
However... both are pretty bad practice. You should read up on the DAO and Repository design patterns. Using the DAO pattern, you hide the details of the database, only exposing the knowledge of a persistence layer. Then with the Repository pattern you expose methods that allow you to manipulate a particular data-set without any care for how that data is retrieved and/or stored.
Using dependency injection you would then inject the repository into a model that does a specific task with that data. Again, you would then pass that model into your view-model which simply displays the information that is available from the model.
One of the big reasons why you keep your data access out of the view models in MVVM is to help with testing. One of the huge advantages of using MVVM is in making more of your code testable, without taking a dependency on the View. By making your view model call an extension method, you have no way of abstracting out the data store calls. This means that when you do your unit testing, you must always have data in the database, ready to be queried against. It also means your data base will fill up with a bunch of crap data that is inserted when your unit tests are ran. You want to hit your data-base when you are writing integration tests, but not really when you are just testing the functionality of your view models.
Abstracting the data access out in to a service or repository, that is hidden behind an interface allows you to test your code, without having to deal with having a connection to the database. You would create fakes or mocks.
This way, your code would do this:
private IMyRepository repository;
public MainWindowViewModel(IMyRepository repo)
{
this.repository = repo;
}
public Task SaveObject(MyObject obj)
{
return this.repository.Save(obj);
}
When you unit test, you just provide a mock, or fake, to your view model constructor and let it hit the save method on those instead.
Your use of an extension method still means you are tightly coupled to your data-layer. It might be abstracted in to a different file, but your view-model is still tightly coupled due to the fact that you can't swap out the data-access without re-writing the original extension method.
The other benefit of this, is that other view models may use the same methods if they need to ask for data. This saves having to copy & pasting the code into extension methods for each view model that might need it or creating an instance of a view model just to get access to its extension methods to fetch your data. View models are typically limited to one view, but the data they are provided with can be used on n views.

Pattern for retrieving complex object graphs with Repository Pattern with Entity Framework

We have an ASP.NET MVC site that uses Entity Framework abstractions with Repository and UnitOfWork patterns. What I'm wondering is how others have implemented navigation of complex object graphs with these patterns. Let me give an example from one of our controllers:
var model = new EligibilityViewModel
{
Country = person.Pathway.Country.Name,
Pathway = person.Pathway.Name,
Answers = person.Answers.ToList(),
ScoreResult = new ScoreResult(person.Score.Value),
DpaText = person.Pathway.Country.Legal.DPA.Description,
DpaQuestions = person.Pathway.Country.Legal.DPA.Questions,
Terms = person.Pathway.Country.Legal.Terms,
HowHearAboutUsOptions = person.Pathway.Referrers
};
It's a registration process and pretty much everything hangs off the POCO class Person. In this case we're caching the person through the registration process. I've now started implementing the latter part of the registration process which requires access to data deeper in the object graph. Specifically DPA data which hangs off Legal inside Country.
The code above is just mapping out the model information into a simpler format for the ViewModel. My question is do you consider this fairly deep navigation of the graph good practice or would you abstract out the retrieval of the objects further down the graph into repositories?
In my opinion, the important question here is - have you disabled LazyLoading?
If you haven't done anything, then it's on by default.
So when you do Person.Pathway.Country, you will be invoking another call to the database server (unless you're doing eager loading, which i'll speak about in a moment). Given you're using the Repository pattern - this is a big no-no. Controllers should not cause direct calls to the database server.
Once a C ontroller has received the information from the M odel, it should be ready to do projection (if necessary), and pass onto the V iew, not go back to the M odel.
This is why in our implementation (we also use repository, ef4, and unit of work), we disable Lazy Loading, and allow the pass through of the navigational properties via our service layer (a series of "Include" statements, made sweeter by enumerations and extension methods).
We then eager-load these properties as the Controllers require them. But the important thing is, the Controller must explicitly request them.
Which basically tells the UI - "Hey, you're only getting the core information about this entity. If you want anything else, ask for it".
We also have a Service Layer mediating between the controllers and the repository (our repositories return IQueryable<T>). This allows the repository to get out of the business of handling complex associations. The eager loading is done at the service layer (as well as things like paging).
The benefit of the service layer is simple - more loose coupling. The Repository handles only Add, Remove, Find (which returns IQueryable), Unit of Work handles "newing" of DC's, and Commiting of changes, Service layer handles materialization of entities into concrete collections.
It's a nice, 1-1 stack-like approach:
personService.FindSingle(1, "Addresses") // Controller calls service
|
--- Person FindSingle(int id, string[] includes) // Service Interface
|
--- return personRepository.Find().WithIncludes(includes).WithId(id); // Service calls Repository, adds on "filter" extension methods
|
--- IQueryable<T> Find() // Repository
|
-- return db.Persons; // return's IQueryable of Persons (deferred exec)
We haven't got up to the MVC layer yet (we're doing TDD), but a service layer could be another place you could hydrate the core entities into ViewModels. And again - it would be up to the controller to decide how much information it wishes.
Again, it's all about loose coupling. Your controllers should be as simplistic as possible, and not have to worry about complex associations.
In terms of how many Repositories, this is a highly debated topic. Some like to have one per entity (overkill if you ask me), some like to group based on functionality (makes sense in terms of functionality, easier to work with), however we have one per aggregate root.
I can only guess on your Model that "Person" should be the only aggregate root i can see.
Therefore, it doesn't make much sense having another repository to handle "Pathways", when a pathway is always associated with a particular "Person". The Person repository should handle this.
Again - maybe if you screencapped your EDMX, we could give you more tips.
This answer might be extending out a little too far based on the scope of the question, but thought i'd give an in-depth answer, as we are dealing with this exact scenario right now.
HTH.
It depends on how much of the information you're using at any one time.
For example, if you just want to get the country name for a person (person.Pathway.Country.Name) what is the point in hydrating all of the other objects from the database?
When I only need a small part of the data I tend to just pull out what I'm going to use. In other words I will project into an anonymous type (or a specially made concrete type if I must have one).
It's not a good idea to pull out an entire object and everything related to that object every time you want to access some properties. What if you're doing this once every postback, or even multiple times? By doing this you might be making life easier in the short term at the cost of you're making your application less scalable long term.
As I stated at the start though, there isn't a one size fits all rule for this, but I'd say it's rare that you need to hydrate that much information.

Services and Repositories in DDD (C#)

How do Services and Repositories relate to each other in DDD? I mean, I've been reading up on DDD for the past 2 days and everywhere I go, there's always a Service layer and there's always a Repository layer. How do these differentiate or compliment each other?
From what I've read, isn't the Repository the layer responsible for delegating interactions between the application and the data?
So, what's the need for the Service layer if it has to implement the Repository to interact with the data anyway even though the Repository probably already implements the methods needed to do so?
I'd appreciate some enlightenment on the subject.
P.S. Don't know if this will help any, but I'm working with an ASP.NET MVC 2 application in which I'm trying to implement the Repository pattern. I just finished implementing the Dependency Injection pattern (for the first time ever)...
UPDATE
Okay, with so many answers, I think I understand what the difference is. So, to review (correct me if I'm wrong):
A Repository layer interacts only with a single object out of the database or the ORM, IEmployeeRepository -> Employee.
A Service layer encapsulates more complex functionality on objects returned from Repositories, either one or multiple.
So, then I have a sub question. Is it considered bad practice to create abstract objects to be sent to my views? For example an AEmployee (A for abstract because to me I means interface) which contains properties from Employee and X or X?
Actually, one more subquestion. If a Service layer can be considered "tuned" for an application does it need to be implemented with an interface?
The Service will use a Repository to retrieve an Entity and then call methods on it (the Entity) to perform the Command/task.
True, a repository works with data (ie. SQL, Webservice etc.) but that's the only job. CRUD operations, nothing more. There is no place for stored procedure based busines logic.
The service (or business logic layer) provides the functionality. How to fullfill a business request (ie. calculate salary), what you have to do.
Oh, and this is a really nice DDD book:
http://www.infoq.com/minibooks/domain-driven-design-quickly
As a concrete example a Shopping Cart application might have the following services:
ShoppingCartService - manages a cart of items with add/remove/update support etc.
OrderService - take a cart, converts it to an order and handles the payment process etc.
each of these services needs to talk a "data source" for CRUD operations. This is where the Repository pattern comes in handy as it abstracts the loading and saving of data to and from the data source be it a database, web service or even in-memory cache.
When you want to create a quick prototype of your application without having to deal with database setup, schema, stored procedures, permissions, etc. you can create a cache or fake repository in a matter of minutes.
For the example above your prototype might start off with the following:
FakeCustomerRepository
FakeAddressRepository
FakeCartRepository
FakeCartLineItemRepository
FakeOrderRepository
FakeOrderLineItemRepository
once your prototype is ready to evolve to the next level you can implement these against a real database:
SQLCustomerRepository
SQLAddressRepository
SQLCartRepository
SQLCartLineItemRepository
SQLOrderRepository
SQLOrderLineItemRepository
From what I can remember, the repository is the final class before the data. The service class can act on data retrieved from the repository. The repository is really just meant to get data to somebody else to do the work. The service layer can provide things such as business logic that all data must pass through. It could also provide for a translation between the application logic and the data layer. But again, this is just what I can remember.
There's no golden standard that defines a service or a repository. In my applications a repository is (as you say) an interface into a database. A service has full access to a repository - but the service exposes a subset of functionality to its consumers.
Think of the repository as more low level. The repository has to expose many ways of accessing the underlying database. A service might combine calls to a repository with other code that only makes sense at a code level (i.e. not in the database), such as access to other state in the application, or validation/business logic that can't easily be applied in a database.

Access Repository through Service or directly?

is itIa good coding standard to allow ASP.NET MVC controller actions to access a repository directly (even though a service layer is present for the heavy lifting, e.g. LoginService.Authorize() ) to retrieve, add, or update data? Or should everything go through the service, and from there to the repository?
For smaller applications/webs, i tend not to use service layer, because it just maps Repositories methods 1:1, and I loose KISS. But in the end, it depends on business model; repository abstracts db access, and services encapsulates logic.
It's better to go through the service layer (depending on how you've implemented it though), because that's the point of it - to be a single access point, thus any business-specific things you do there, are represented and implemented across all callers.
It really depends on the complexity. If you're dealing with any transcation scoping, I'd definitely decouple that away from the controller into your service layer.
In my opinion it will depends on your design/architecture. What's the purpose of a repository ? Do CRUD operations (Create, Read, Update and Delete).
If you're using the anemic domain models in a classic three-tiers architecture all logic applied to the models are made in the services.
In this case the choice is obvious : You shouldn't call the repository directly.
Why ? Since your models are silly and the logic is in the services you could create invalid models. If you can call the repository you could create/update an invalid model in database. If you call the services it should be able to correct or fill your model before create/update it.
If you're using a rich domain model in an onion architecture it's different. Since your models are supposed to be always valid (when you create one from the constructor or from the factory all validations has been performed and when you update one it's the same thing) you can without any problem call directly the repository.
In this context all the logic is in the models directly and the services are just used to stored the logic that doesn't belong to one model specificly.
Now the question is not "how to use repository" but "what design/architecture do I need ?" and the first question will be answered :-)

Categories

Resources