I am making a web api and have created several classes, the class controller and the service as well as the dto and the model.
In the controller I have the methods for post and get and the business logic is in the service
My question is how can I make the queries from the model class and map the queries to the dto
Service Layer:
public class GermanyService : IGermanyService
{
public Task<IEnumerable<GermanyDto>> All()
{
throw new NotImplementedException();
}
public Task Create(GermanyDto germany)
{
throw new NotImplementedException();
}
}
Controller:
public class GermanyController
{
private readonly IGermanyService _germanyService;
public GermanyController(IGermanyService service)
{
_germanyService = service;
}
[HttpGet]
public async Task<IEnumerable<GermanyDto>> Get(int id)
{
return await _germanyService.All();
}
[HttpPost]
public async Task Post([FromBody]GermanyDto dto)
{
await _germanyService.Create(dto);
}
Okay :)
Use an interface implementation ->
seggregate your business logic's interfaces, so you have many of them, split into their single responsibilities and then join them in one:
Example
public interface IStreetName {
string StreetName{get;set;}
}
public interface IPostCode {
string PostCode {get;set;}
}
... other implementations for an Address DTO f.x.
then
public interface IAddress : IPostCode, IStreetName, ...
{
//should be empty
}
now you can Implement Iaddress on your DAL object, and not need an actual DTO -> because you ONLY reference the interface in your business logic.
etc.
Obviously, you would have to rename the intefaces for the properties on your "GermanyDTO", which I don't know what looks like.
EDIT:
Using mappers like "auto-mappers" or the like is usually a sign of 2 things.
1: You don't understand how to write effective mapping yourself.
2: Using a framework to accomplish something, doesn't absolve you from testing. And frameworks are notoriously difficult to test.
(Because, following proper procedure, you would have to test the interface between your code and the framework, and by extension the code between framework and 3rd part component, failing to do so, will setup you up for risks, between what you THINK the framwork does, and what it ACTUALLY does)
So Yes, using something like "Automapper" is at best a supression of a symptom rather than a cure.
Because the root cause is failing to understand how interfaces solve mappings.
And using a tool, to do something you can do cleaner yourself, and improve the structure of your entire system as a result? Is a no-brainer.
Just notice your own statement:
"Do you think it is effective? Automapper solves some of my issues"
You are seriously going to implement a direct dependency in your system, because of a framework?
You are admitting to writing bad code, because a framework can take away ... what? A little bit of boiler plate?
Related
I know this might be an opinion-based question, but, I'd rather to ask as there might be some design principle for this.
I'm having a .net C# web API application to expose few APIs to retrieve some data from a database. I'm also using mediateR on this project. The APIs, they all get one request object but all of them have exact same properties. Imagine, we have a BaseProduct class from which ProductA, ProductB, and ProductChave been inherited in the domain project. Now, I need to expose APIs to return these three objects to the users. Here's an example of two of the request objects.
With Inheritance:
public abstract class BaseGetProductRequest { // the props here }
public class GetProductARequest : BaseGetProductRequest, IRequest<GetProductAResponse> { }
public class GetProductBRequest : BaseGetProductRequest, IRequest<GetProductBResponse> { }
public class GetProductAResponse { public ProductA[] Products {get; set;} }
Each of the above requests also has its own request handler class.
With using generics: (BaseProduct is a domain object class from which different product types are inherited)
public class GetProductRequest<TProductType> : IRequest<TProductType[]> where TProductType : BaseProductType { // all props in here }
Which will be used like this in an API:
public async Task<ProductA[]> Get([FromRoute] GetProductRequest<ProductA> request) { // API body }
So, the question is: Which one the following would be a better approach to take from a design point of view?
To take the Inheritance approach as above
Or to implement the requests and request handlers using generics so we'll end up with less files
Personally, I would prefer the first approach as I want to literally have separate request objects for each API, this way it looks cleaner to me besides that would be consistent with the rest of the code as well (as not all the request objects can be implemented generically). Besides, if by any chance in the future there is a need to add a type-specific property for a request object, then, our code will be more flexible with that change.
Is there like any specific design guidelines which recommends for example taking one over another? Thanks for your opinions in advance.
Sure the inheritance approach will give your project a higher performance, due to the re-usability of compiled requests
I am implementing a generic repository pattern, I have done this quite a few times now but every time I do it there is something bugging me.
If I have a database design like below. (All the tables relate to one another.) And I make a call like the following
public IEnumerable<Domain> GetRealEstate()
{
return _repository.GetAll();
}
I can get all the models from just that one call (The wonders of EF). The thing that bugs me is the fact that I have to say Domain in the method call, from the domain entity I will get all the relevant entity (Lazy loading) Companies etc. etc. It just feels wrong to use domain entity to get all the companies etc. etc. The repo pattern that I am using is a straight forward one.
Is there a better way of writing the methods so that it does not look so weird?
Below is sample code that i have
Controller
[RoutePrefix("api/realestate")]
public class RealEstateController : ApiController
{
private readonly IRealEstateService _service;
public RealEstateController(IRealEstateService service)
{
_service = service;
}
[Route("")]
public Task<Domain> GetRealEstates()
{
var collection = _service.GetRealEstate();
return null;
}
[Route("{domainName}")]
public Task<Domain> GetRealEstate(string domainName)
{
}
}
Service
public class RealEstateService : IRealEstateService
{
private readonly IRealEstateRepository _repository;
public RealEstateService(IRealEstateRepository repository)
{
_repository = repository;
}
public IEnumerable<Domain> GetRealEstate()
{
return _repository.GetAll();
}
}
Sense & Responsibility.... This is a dilemma I see more people struggle with. I think the key to feeling easier about it is that Domain can be considered an aggregate root that encapsulates the whole object graph it's the owner of.
Let's look at a very common example that's closer than you might think, DbSet. DbSet is a repository. But I think most of us think it's totally acceptable, even good practice, to write a query like
context.Domain.Include(d => d.Companies)....
Nobody will say, what has a DbSet<Domain> to do with Company? Even when we add a Domain to the DbSet, and by doing that we add an entire object graph, nobody will feel any inclination to add each object through its "proper" DbSet. That would a totally useless hell of a job.
If this wasn't good practice, EF (or any ORM) wouldn't have navigation properties. Think of that... nightmare.
I'm using Web API v2 and I have a handful of models that I need to do CRUD operations for. For example, I have an Allergy model and a Prescription model. In the application itself I have viewmodels which can turned into their appropriate models, but for simplicity's sake let's just say I take the model straight in the Web API controller.
So something like this:
public class PrescriptionsController
{
public HttpResponseMessage Put(Prescription model)
{
// saved to the DB
}
... (other CRUD operations)
}
I also have the same for the Allergy model:
public class AllergiesController
{
public HttpResponseMessage Put(Allergy model)
{
// saved to the DB
}
... (other CRUD operations)
}
Both models have different properties but are handled exactly the same way - in fact I have about 3 other models which are handled exactly the same way for each CRUD operation. I hate to do have 5 different endpoints that are basically copied and pasted code.
So my question is this:
Can I make a generic controller to handle all of these models? Something like MyCommonController<T>? (but with a better name of course!) Can the Web API handle the routing in that scenario? Is that even a good idea?
In the end I didn't try a generic controller. It seemed like it might be possible via jumping through some hoops with routing.
However, the fact that routing modifications to get this to work were so complicated it kind of negated the benefit I would get. I wanted to keep things simple. So I just created a generic base class instead:
class MyBaseController<TModel> : ApiController
{
public TModel Get(int id) { ... }
}
and had each type inherit from it:
class PrescriptionsController : MyBaseController<Prescription> { }
And that worked like charm, didn't have to mess with routing or anything. It makes it clear what's happening and is pretty maintainable.
I've been playing around with asp.net MVC3 a bit and have been struggling to decide where to place my business logic. I've settled on using a service layer for now:
public class AnimalsService : IAnimalsService
{
private readonly IAnimalsRepository _animalsRepository;
public AnimalsService(IAnimalsRepository animalsRepository)
{
_animalsRepository = animalsRepository;
}
public IQueryable<Animal> GetFiveLeggedAnimals()
{
...
}
}
The controller would look something like this:
public class AnimalsController : Controller
{
private readonly IAnimalsService _animalsService;
public AnimalsController(IAnimalsService animalsService)
{
_animalsService = animalsService;
}
public ViewResult ListFiveLeggedAnimals()
{
var animals = _animalsService.GetFiveLeggedAnimals();
return View(animals);
}
}
I have basic CRUD logic in the repository (All, Find, UpdateOrInsert, Delete). If I want to use these CRUD methods in my controller:
1) Do I have to create wrapper methods in the service for these respository calls?
2) Would it not make more sense for me to just include the GetFiveLeggedAnimals method and other business logic in the repository?
3) Could I implement the IAnimalsRepository interface in the AnimalsService and then call the base methods (I realise this is possible but I assume its bad practice)?
1) Do I have to create wrapper methods in the service for these respository calls?
Mostly, yes. Typically, you want to offer CRUD for your domain models in the service layer. This way, the controller does not need to work with the repository directly (in fact, it never should). You can add more more sophisticated logic later without having to change external code. For example, consider you wanted to implement a newsfeed. Now every time a five-legged animal is inserted, you want to create a news item and push it to five-legged-animal-fans. Another common example is email notifications.
2) Would it not make more sense for me to just include the GetFiveLeggedAnimals method and other business logic in the repository?
Business logic should be in the Service Layer or in the Domain Model objects themselves, and only there. In fact (see 3), I wouldn't specifically offer an IAnimalRepository at all, if possible.
For instance, in a NoSQL-Environment, the database driver pretty much is a repository. On the other hand, when using a complex ORM mapping and stored procedures (where part of the biz logic is in the DB), you don't really have a choice but offer explicit interfaces that know the stored procedures.
I'd go for a IRepository<T> and use the Query Object pattern, if possible. I think LINQ can also be considered a Query Object / Repository based pattern.
3) Could I implement the IAnimalsRepository interface in the AnimalsService and then call the base methods (I realise this is possible but I assume its bad practice)?
To call the base methods, you'd have to inherit from a concrete implementation, e.g. from ConcreteAnimalsRepository.
Also, if your service implements the IAnimalsRepository interface directly or indirectly, it makes the (unfiltered) CRUD operations available to everyone.
My take: Don't inherit, aggregate. A service layer has a repository, but it isn't a repository itself: The service layer handles all the additional application logic (permissions, notifications) and the repository is a very thin wrapper around the db layer.
As an extreme example, what if deleting something directly was forbidden, and only the service would be allowed to make use of it when inserting a newer revision of sth.? This can be easily built when aggregating.
Repository by definition should be a generic collection-like class that abstracts DB interactions. It would contain typical methods for persistence like Get(object id), Add(T), Remove(T) and possibly implement IQueryable<T>.
The service would look like the following code.
public class AnimalsService : IAnimalsService
{
private readonly IRepository<Animal> _repository;
public AnimalsService(IRepository<Animal> repository)
{
_repository = repository;
}
public IEnumerable<Animal> GetFiveLeggedAnimals()
{
// animal specific business logic
}
}
I think is not good to use simple CRUD operation in the Controller and have a wrapper in the Service class, you should keep all business logic in the service layer, not in controller
for example you want to create a new Animal
in the controller you will have method
look at the example
// not good design
public ActionResult Create(AnimalInput input)
{
Animal animal = new Animal { Name = input.Name}; // set the other propreties
// if you have a CRUD operations in service class you will call
animalService.UpdateOrInsert(animal);
}
// better disign
public ActionResult Create(AnimalInput input)
{
animalService.Create(input.Name);
}
in the service class implementation you should have
follow
public void Create(string name)
{
Animal animal = new Animal { Name = input.Name};
animalRepository.UpdateOrInsert(animal);
}
for the methods like GetAll or GetFiveLeggedAnimals(); you can have wrapper in the service classes I think it's ok . And I want to give you adives allways when you write some code in controller or in Service class keep in mind how you will test this code
and don't forget about SOLID
Using LINQ TO SQL as the underpinning of a Repository-based solution. My implementation is as follows:
IRepository
FindAll
FindByID
Insert
Update
Delete
Then I have extension methods that are used to query the results as such:
WhereSomethingEqualsTrue() ...
My question is as follows:
My Users repository has N roles. Do I create a Roles repository to manage Roles? I worry I'll end up creating dozens of Repositories (1 per table almost except for Join tables) if I go this route. Is a Repository per Table common?
If you are building your Repository to be specific to one Entity (table), such that each Entity has the list of methods in your IRepository interface that you listed above, then what you are really doing is an implementation of the Active Record pattern.
You should definitely not have one Repository per table. You need to identify the Aggregates in your domain model, and the operations that you want to perform on them. Users and Roles are usually tightly related, and generally your application would be performing operations with them in tandem - this calls for a single repository, centered around the User and it's set of closely related entities.
I'm guessing from your post that you've seen this example. The problem with this example is that all the repositories are sharing the same CRUD functionality at the base level, but he doesn't go beyond this and implement any of the domain functions. All the repositories in that example look the same - but in reality, real repositories don't all look the same (although they should still be interfaced), there will be specific domain operations associated with each one.
Your repository domain operations should look more like:
userRepository.FindRolesByUserId(int userID)
userRepository.AddUserToRole(int userID)
userRepository.FindAllUsers()
userRepository.FindAllRoles()
userRepository.GetUserSettings(int userID)
etc...
These are specific operations that your application wants to perform on the underlying data, and the Repository should provide that. Think of it as the Repository represents the set of atomic operations that you would perform on the domain. If you choose to share some functionality through a generic repository, and extend specific repositories with extension methods, that's one approach that may work just fine for your app.
A good rule of thumb is that it should be rare for your application to need to instantiate multiple repositories to complete an operation. The need does arise, but if every event handler in your app is juggling six repositories just to take the user's input and correctly instantiate the entities that the input represents, then you probably have design problems.
Is a Repository per Table common?
No, but you can still have several repositiories. You should build a repository around an aggregate.
Also, you might be able to abstract some functionality from all the repositories... and, since you are using Linq-to-Sql, you probably can...
You can implement a base repository which in a generic way implements all this common functionality.
The following example serves only to prove this point. It probably needs a lot of improvement...
interface IRepository<T> : IDisposable where T : class
{
IEnumerable<T> FindAll(Func<T, bool> predicate);
T FindByID(Func<T, bool> predicate);
void Insert(T e);
void Update(T e);
void Delete(T e);
}
class MyRepository<T> : IRepository<T> where T : class
{
public DataContext Context { get; set; }
public MyRepository(DataContext context)
{
Context = Context;
}
public IEnumerable<T> FindAll(Func<T,bool> predicate)
{
return Context.GetTable<T>().Where(predicate);
}
public T FindByID(Func<T,bool> predicate)
{
return Context.GetTable<T>().SingleOrDefault(predicate);
}
public void Insert(T e)
{
Context.GetTable<T>().InsertOnSubmit(e);
}
public void Update(T e)
{
throw new NotImplementedException();
}
public void Delete(T e)
{
Context.GetTable<T>().DeleteOnSubmit(e);
}
public void Dispose()
{
Context.Dispose();
}
}
To me the repository pattern is about putting a thin wrapper around your data access methodology. LINQ to SQL in your case, but NHibernate, hand-rolled in others. What I've found myself doing is create a repository-per-table for that is extremely simple (like bruno lists and you already have). That is responsible for finding things and doing CRUD operations.
But then I have a service level that deals more with aggregate roots, as Johannes mentions. I would have a UserService with a method like GetExistingUser(int id). This would internally call the UserRepository.GetById() method to retrieve the user. If your business process requires the user class returned by GetExistingUser() to pretty much always need the User.IsInRoles() property to be filled, then simply have the UserService depend upon both the UserRepository and RoleRepository. In pseudo code it could look something like this:
public class UserService
{
public UserService(IUserRepository userRep, IRoleRepository roleRep) {...}
public User GetById(int id)
{
User user = _userService.GetById(id);
user.Roles = _roleService.FindByUser(id);
return user;
}
The userRep and roleRep would be constructed with your LINQ to SQL bits something like this:
public class UserRep : IUserRepository
{
public UserRep(string connectionStringName)
{
// user the conn when building your datacontext
}
public User GetById(int id)
{
var context = new DataContext(_conString);
// obviously typing this freeform but you get the idea...
var user = // linq stuff
return user;
}
public IQueryable<User> FindAll()
{
var context = // ... same pattern, delayed execution
}
}
Personally I would make the repository classes internally scoped and have the UserService and other XXXXXService classes public so keep your consumers of the service API honest. So again I see repositories as more closely linked to the act of talking to a datastore, but your service layer being more closely aligned to the needs of your business process.
I've often found myself really overthinking the flexibility of Linq to Objects and all that stuff and using IQuerable et al instead of just building service methods that spit out what I actually need. User LINQ where appropriate but don't try to make the respository do everything.
public IList<User> ActiveUsersInRole(Role role)
{
var users = _userRep.FindAll(); // IQueryable<User>() - delayed execution;
var activeUsersInRole = from users u where u.IsActive = true && u.Role.Contains(role);
// I can't remember any linq and i'm type pseudocode, but
// again the point is that the service is presenting a simple
// interface and delegating responsibility to
// the repository with it's simple methods.
return activeUsersInRole;
}
So, that was a bit rambling. Not sure if I really helped any, but my advise is to avoid getting too fancy with extension methods, and just add another layer to keep each of the moving parts pretty simple. Works for me.
If we write our repository layer as detailed as Womp suggests, what do we put in our service layer. Do we have to repeat same method calls, which would mostly consists of calls to corresponding repository method, for use in our controllers or codebehinds? This assumes that you have a service layer, where you write your validation, caching, workflow, authentication/authorization code, right? Or am I way off base?