Recently I've read article "The Entity Framework In Layered Architecture" and there is written we can send EF-entities to client through WCF. But in many threads on Stackoverflow people tell that POCO(DTO)-objects should be used when we use WCF.
And I have some questions.
Why did Microsoft add DataContract attribute to EF-entities? Does Microsoft wanted us to use these objects everywhere in our applications? Or this is only for very simple applications and for rapid development?
If I use POCO-objects, should I create auto generated EF-Entities, POCO-Entities and after that use any mapping library between them? Or I should use only POCO-objects in all components of my application?
If I already have my own business entity, which has some methods, and it should be mapped to POCO object, on which layer should I convert POCO-object to my entity (for example, I have persistence layer, business logic layer, service layer(WCF), presenter layer (client, use WCF), UI layer)? Or I shouldn't make such my own entities?
Thanks in advance
1.Why did Microsoft add DataContract
attribute to EF-entities? Does
Microsoft wanted us to use these
objects everywhere in our
applications? Or this is only for very
simple applications and for rapid
development?
Generally speaking, it is a bad idea to expose your EF-Entities in the service layer because that hardly couples your service layer and model representation. so any changes done in the model ends affecting directly your services, not a good idea. also you will have to version your service layer in some moment, so avoid to expose the EF entities in your service layer.
2.If I use POCO-objects, should I create auto generated EF-Entities,
POCO-Entities and after that use any
mapping library between them? Or I
should use only POCO-objects in all
components of my application?
You can use POCO objects inside your service layer, to decouple it from any underlying layers (see Automapper, to cover the Entity-DTO mapping cost). but you could still use the autogenerated EF-entities among the data and business layers in your architecture. just try to not rely in EF specific features of your generated domain model in other layers different from data layer. to ease the migration to another ORM frameworks.
If I already have my own business
entity, which has some methods, and it
should be mapped to POCO object, on
which layer should I convert
POCO-object to my entity (for example,
I have persistence layer, business
logic layer, service layer(WCF),
presenter layer (client, use WCF), UI
layer)? Or I shouldn't make such my
own entities?
Service layer http://msdn.microsoft.com/en-us/library/ms978717.aspx. you would be using your domain model transparently among the server tier (persistence, business, service and presenter layers) of your application, and the only layer that will require you a DTO mapping is the service layer, see question 1. (additionally if you are using ViewModels inside your the presenter layer -nice idea- you will require to use POCOs-mapping in the presenter layer too).
You can have POCO entities handwritten and completely separated from the persistence layer. SDReys is right, using generated EF entities as your model is smelly.
Here is the rough layout for a simple POCO model and the context to support it.
public class MyApplicationContext : ObjectContext, IMyApplicationContext {
public MyApplicationContext() : base("name=myApplicationEntities", "myApplicationEntities")
{
base.ContextOptions.LazyLoadingEnabled = true;
m_Customers = CreateObjectSet<Customer>();
m_Accounts = CreateObjectSet<Account>();
}
private ObjectSet<Customer> m_Customers;
public IQueryable<Customer> Customers {
get { return m_Customers; }
}
private ObjectSet<Account> m_Accounts;
public IQueryable<Account> Accounts {
get { return m_Accounts; }
}
public Account CreateAccount(Customer customer) {
var account m_Accounts.CreateObject();
account.Customer = customer;
return account;
}
public Customer CreateCustomer() {
return m_Customers.CreateCustomer();
}
public void AddAccount(Account account) {
m_Accounts.AddObject(account);
}
public void AddCustomer(Customer customer) {
m_Customers.AddCustomer(customer);
}
}
public class Account {
public int Balance {get;set;}
virtual public Customer{get;set;}
}
public class Customer {
public string Name {get;set;}
virtual public List<Account> Accounts{get;set;}
}
Related
My goal is async loading of related entities using DBContext.
Let imagine two projects. The first named MyApp.Domain and contains domain entities.
namespace MyApp.Domain
{
public class PlanPage
{
public Guid Id { get; set; }
}
}
namespace MyApp.Domain
{
public class PlanPageDay
{
public Guid Id { get; set; }
public Guid PlanPageId { get; set; }
}
}
The second project named MyApp.Infrastructure.EntityFramework and contains configuration of projection entities to database. It also contains class which extends domain entity and implements Entity framework specific logic.
namespace MyApp.Infrastructure.EntityFramework.Models
{
public class PlanPageEntity : PlanPage
{
private readonly ApplicationDbContext _applicationDbContext;
protected PlanPageEntity(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
public ICollection<PlanPageDay>? Days { get; set; }
public async Task<ICollection<PlanPageDay>> GetDays()
{
return Days ??= await _applicationDbContext.PlanPageDays
.Where(pd => pd.PlanPageId == Id)
.ToListAsync();
}
}
}
The purpose of this example is simple. We separate infrastructure code from domain code. Look how do we plan to use this concept:
// Entity initializing code. Placing somewhere in domain logic.
var plan = new PlanPage(/*some constructor arguments*/);
// Entity loading code. Placing somewhere in infrastructure implementation.
public async Task<PlanPage> GetPlanPage(Guid id)
{
return await _applicationDbContext.Set<PlanPageEntity>().FindAsync(id);
}
Note that we tell to Entity framework to use child class (PlanPageEntity) so it can handle all specific things that it can.
The question is: Is it possible to configure the EF so that it allows us to use this concept?
As requested here's a little more details for my opinion stated in the comments.
The main reason why I think your current approach is a bad idea is that it violates the separation of concerns design principle: when you are mixing domain models with data access models, you make your domain logic completely dependent on how you model the data in your database. This quickly limits your options because the database may have some restrictions on how you can model your data that doesn't fit well with the domain logic you want to implement as well as making maintenance difficult. E.g. if you decide to split up one DB table into two then you might have a big task ahead of you in order to make your domain logic work with those two new models/tables. Additionally, making performance optimizations in your database easily becomes a nightmare if not thought through ahead of time - and you shouldn't spend time thinking of optimizing your system before it's necessary.
I know this is a little abstract since I don't know much about your domain but I'm sure I could find more arguments against it.
Instead, separating data access models (and in general all external data models) from your domain models makes it much easier to maintain: if you need to make some changes to your database, you simply need to update the logic that maps the data from your data access models to your domain model - nothing in your domain logic needs to change.
In the examples you have given, you have already logically separated your domain models and data access models into two separate projects. So why not follow through with that thought and separate the two with a binding/mapping layer in-between?
Is it possible to configure the EF so that it allows us to use this concept?
Yes. Essentially you have DTO's, and your Entities derive from your DTOs. So when you fetch an Entity you can return it directly. But if you wouldn't be able to attach a non-Entity, so you'd have to map it. It's going to be inconvenient, and like 99.999% of bespoke entity and repository designs, will be ultimately a waste of time.
This is somewhat similar to the what EF already does for you. Start with persistence-ignorant Entity classes, and introduce persistence-aware runtime subtypes for scenarios that require them, which is basically just Lazy Loading.
I'm fairly new to DDD but I am trying to cram as much as possible as fast as possible. I followed https://github.com/dotnet-architecture/eShopOnContainers as a guide for how to structure my code with Mediatr and EF Core.
Fortunately for this application, the persistence and domain model are the same. Unfortunately for me, my data layer does not match our domain model as it is a legacy db.
So i am separating the domain from persistence which is well and good. But I am having a hard time understanding where if i do this code block in a command handler(trying to make it simple and clear)...
var aggregate = repo.GetById(1234);
aggregate.AddItemToList(item);
repo.SaveChanges();
How can i cause the underlying database context of the repo to be aware of the changes that were applied. Only thing i can think is to have a repo.Update(aggregate) call, that would then try to apply db calls to update various places of the db.
This seems like a smell to me.
Any insights would be great.
Thank you!
Edit:
Should the repository pattern with a separate Domain and Persistence layer return the presistance layer's model or the domain's?
For example:
I have a aggregate Company. And i have a database table called CompanyLegacy which is modeled in the persistence layer using entity framework core.
Should my repository be CompanyLegacyRepository or CompanyRepository? If CompanyRepository, that would mean i query the CompanyLegacy table, and map it to a Company domain model then return it. This model, would not be change tracked. This is where my issue comes from.
But if I'm supposed to do a CompanyLegacyRepository then it seems like that doesn't adhere to DDD guidelines where all actions to be applied to the aggregateroot.
Should the repository pattern with a separate Domain and Persistence
layer return the persistence layer's model or the domain's?
Repository should return your Domain model. If you are using DTOs (such as CompanyLegacy) in your Infrastructure layer, it is the responsibility of your Repository to map them to your Domain models. Please note that in a Layered Architecture, the Application layer is not supposed to know about the DTOs used in the Infrastructure layer... it's your Domain models which are the heart of your application. See this question which is closely related to yours.
Your Repository should be called CompanyRepository. You can define an interface for this repository like:
public interface ICompanyRepository
{
// Company is your domain model not DTO (i.e. your legacy model)
Company GetById(int id);
void Add(Company);
void Update(Company);
}
Change Tracking
Entity Framework change tracking has it's limitations, this question is an example of one of those Disconnected Scenarios, where we cannot rely on EF Change Tracking (because of DTOs). The implementation of the above repository would be like:
public CompanyRepository: ICompanyRepository
{
Private MyDbContext _context;
public CompanyRepository(MyDbContext myDbContext) { _context = myDbContext; }
public Company GetById(int id)
{
var companyLegacy = _context
.CompanyLegacy
.AsNoTracking()
.Where(c => c.id = id)
.FirstOrDefault();
return MyMapper.ToCompany(companyLegacy);
}
public void Add(Company company)
{
var companyLegacy = MyMapper.ToLegacy(company);
_context.Add(companyLegacy);
_context.SaveChanges();
}
public void Update(Company)
{
var companyLegacy = MyMapper.ToLegacy(company);
_context.Update(companyLegacy);
_context.SaveChanges();
}
}
This tutorial is helpful for more advanced operations and you can find more info about EF Core change tracking here.
this answer is related to EF 4/5/6 (not core) but gives you some idea about using unique identifier to decide if an entity should be Added or Updated.
i'm beginner in repository and layerd application and i don't inderstand well which is the interaction and the relationship between the repositories and business layer classes
Here is an example for purchaese order in 3 layers and I want to review whether correct or not and your correction
for DataAcesslayer
repository OrderRepositolry
Namespece Dal
{
Public class RepositoryOrder
{
POrderContext context = new POrderContext ();
Public IEnumrebale <Order> GetAll ()
{
Context.Orders;
}
// Following code
}
}
for the item of order repositories code :
namespece Dal
{
public class RepositoryOrderItem
{
POrderContext context = new POrderContext();
public IEnumrebale<OrderItem> GetAllItemById(Order o)
{
context.OrderItems.where(i => i.OrderId == o.Id);
}
public OrderItem GetItemById(int id)
{
context.OrderItems.Find(id);
}
//Following code
}
}
for businessLayer here is classOrderBLL code:
namespace BLL
{
public class OrderBLL
{
RepositoryOrder repoOrder = new RepositoryOrder();
RepositoryOrderItem repoItem = new RepositoryOrderItem();
public IList<Order> GetAll()
{
return repoOrder.GetAll();
}
public decimal GetPrixTotal(Order order)
{
var query = from item in repoItem.GetAllItemById(order)
select sum(item=>item.Prix * item.Quantite);
return query;
}
}
}
does the total price calculation is done at the level of repository
or at the level of BLL (we can make this request linq with context
in the repository)?
CRUD method is done at repository and they are called at BLL from
repository is it right?
does the where method in linq corresponds to logical business or
repository (data access layer) since it determines certain rules in
the business?
I'm sure this question will be voted down as "primarily opinion based" but before that happens I'll jump in to give my "primarily opinion based" answer :-)
There are two ways to partition a database application and they depend on how complex and large it will be. Entity Framework examples tend to give a very simplistic model, where the EF Data classes are exposed to the Business layer which then exposes them to the View Model or other layers. This may be correct for simplistic applications but for more complex ones, and ones where the data storage method is not RDBMS (i.e. No-SQL) or where you want to create separation between business and repository data structures it is too simple.
The repository layer should have a set of classes which describe how the data is accessed from the repository. If you have an RDBMS these might be EF POCO classes, but if you have a web-service endpoint as your repository this may be SOAP documents, or REST structures, or other Data Transfer Object. For an RDMBS like SQL Server that uses exclusively stored procedures for accessing its data, the Repository layer might simply be a set of classes which mirror the naming and parameters, and data sets returned by the stored procedures. Note that the data stuctures returned by anything other than an RDBMS might not be coherent - i.e. a "Customer" concept returned by one method call in the repository might be a different data structure to a "Customer" returned by a different call. In this case the repository classes would not suit EF.
Moving to the business object layer - this is where you create a model of the business domain, using data classes, validation classes and process class models. For instance a Process class for recording a sales order might combine a Business Customer, Business Sales Order, Business Product Catalog data concepts and tie in a number of Validation classes to form a single atomic business process. These classes might (if you are doing a very lightweight application) be similar to data at the Repository layer but they should be defined seperately. Its in this layer you hold calculated concepts such as "Sales Order Total" or "VAT Calculation" or "Shipping Cost". They might, or might not, get stored into your Repository but the definition of what they mean are modelled in the business layer.
The business layer provides the classes whose data is copied across into a View Model. These classes again can be very similar (and in the simplest of cases, identical to) the repository classes, but in their job is to model the user interface and user interaction. They might contain only some of the data from the business data classes, depending on the requirements of the UI. These classes should carry out user interface based validation, which they might delegate to the business tier, or might add additional validation to. The job of these classes is to manage the state-machine that is the user interface.
My summary is that in a large scale system you have three sets of classes; data repository interaction, business model interaction, and user interface interaction. Only in the simplest of systems are they modelled as a single set of physical POCO classes.
i am trying to get control over DDD with EF code first. i saw when people work with EF code first then domain classes reside there in same classes. just see a small example.
public class TestDBContext : DbContext
{
public TestDBContext()
: base("name=TestDBContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//modelBuilder.Configurations.Add(new vwCustomerConfiguration());
Database.SetInitializer<TestDBContext>(null);
}
public DbSet<Customer> Customer { get; set; }
public DbSet<Addresses> Addresses { get; set; }
public DbSet<Contacts> Contacts { get; set; }
public virtual DbSet<vwCustomer> vwCustomers { get; set; }
public DbSet<vwMyCustomers> vwMyCustomers { get; set; }
}
customer, address, contact and all domain classes are in same project but i want to put all these domain classes in different project.
just see new project hierarchy which i am thinking to implement. all project name will start with my company then do and project name
here it is
1) Impex.Domain
2) Impex.Storage
3) Impex.Business
4) Impex.UI
so i will have 4 layers and those are domain, Storage, Business and UI. Storage, Business and UI these 3 layer will have reference of Domain layer because these 3 layers Storage, Business and UI may use domain classes.
UI will pass data to business layer and received data from business layer. business layer again will talk to Storage layer where EF code first will be implemented to interact with DB.
if i can successfully complete my project following 4 layers then people should consider my project is based on DDD pattern or not ?
so tell me am i thinking right way. please tell me all your suggestion and guidance. if anyone can foresee any problem then also please aware me in details. thanks
Your question seems largely around the structure of your solution, as with most things in our industry once you understand the principles of a thing (DDD in this case) the structure seems to sort it self out.
I would point out a couple of things to help you along your way
1) Impex.Domain
Keep your entities clean don't reference EF from this project
Capture your business logic in your entities & aggregates rather than in a 'business' layer, your entities should be responding to events and actions rather than having a 'layer' that tells it what to
As a poor example, do something like
employee.takeLeave(days)
Instead of
employee.daysOff = days;
i.e. Modifying the state of the entity should be captured internally to the entity.
2) Impex.Storage
Since you are using EF (and not going to pollute your Domain models with EF related attributes) you will have to use the Fluent Api to configure your EF model (see msdn, ef tuts, and SO to get some ideas) in particular, primary keys and indexes will need to be configured here.
Something like
modelBuilder.Entity<Employee>().HasKey(t => t.EmployeeID);
Other than that nothing exiting here use standard repository patters etc.
3) Impex.Business & Impex.UI
As mentioned in point 1 it doesn't make sense to have a business layer, rather what this layer would be is an Application or Service layer, here you would load the entity or aggregate and invoke the work to be completed.
Also a responsibility of the layer would be to map between ViewModels &/OR Request & Response POCOs (sent to and from your UI/Api), you would not expose your Domain Models outside of the Domain boundary see hexagonal architecture
Last note:
DDD does not dictate the architecture! It's a set of principles to guide you, but you can implement as a 1 tier, 3 tier, CQRS or anyother architectural pattern you like as long as you adhere to the tenants of DDD.
Good luck.
Tools: Mvc4, Sql server, Nhibernate
I am learning Ntier architecture and plan to learn this with a small example. This will be a student registration application which will have a form for
a. first name
b. last name
c. address
d. Student Id
The application will be able to
a. Get student by Id
b. Get all students
c. Register new students/Save student
d. Edit a student
e. Delete a student
I plan to have the following tiers
Presentation layer (seperate project mvc 4 application)
--- html for student form goes here. I can use jquery etc here
--- my controller will call the service
Service layer (seperate project : class library project. In this case only the web will be my client. I will learn to use webAPI or wcf for this later in another project)
--- StudentService here
--- IstudentService here
Business layer : (seperate project : class library project)
??
Data layer : (seperate project : class library project)
??
Database : (sql server database)
Now I got confused and my questions are:
where will I create my student model (which layer ?)
What will I be writing in my business layer for this student example I have.
What will go in my data layer? Which methods will I be writing? Are they methods that will communicate
with the database directly?
Some examples will be great. I will look for a good IOC container.
Here is sample code below:
public interface IStudentService
{
IEnumerable<Student> GetStudents();
Student GetStudentById(int id);
void CreateStudent(Student student);
void UpdateStudent(Student student);
void DeleteStudent(int id);
void SaveStudent();
}
public class StudentService : IStudentService
{
private DataContext _datacontext;
public StudentService()
{
_datacontext = new DataContext();
}
public IEnumerable<Student> GetStudents()
{
var students = _datacontext.Students;
return students;
}
public Student GetStudentById(int id)
{
return _datacontext.Students.Find(id);
}
public void CreateStudent(Student student)
{
_datacontext.Students.Add(student);
_datacontext.SaveChanges();
}
public void UpdateStudent(Student student)
{
_datacontext.Entry(student).State = EntityState.Modified;
//_datacontext.Entry(student).State = EntityState.Modified;
_datacontext.SaveChanges();
}
public void DeleteStudent(int id)
{
var student = _datacontext.Students.Find(id);
_datacontext.Entry(student).State = EntityState.Deleted;
_datacontext.SaveChanges();
}
public void SaveStudent()
{
_datacontext.SaveChanges();
}
}
You create your model in your data layer. You will also create models in your presentation tier (for your view models). You would usually do some kind of mapping between your data model and your presentation model in your controller.
Simple apps often don't really need a business layer. Particularly if your app just saves data from forms into tables. However, in an app such as this you might do things like "You can't register for this class unless you've already completed that class" or you might have "You have already registered for more classes than you are allowed" or what not. These are business rules that must be enforced somewhere, and that is usually in the business layer.
Your data layer will probably just be your Entity Framework model. It's just your code to load and save your model to the database.
There are many IoC containers.. I like Ninject, but other people like other ones.. It's generally a matter of personal preference.
The above is how you would do it in a simple application. In more complex applications, you might have a model in your business layer as well. It all depends on the complexity of your application, and whether you need to represent your data at a business level differently than you would at a data model level.
For instance, you might have a list of business objects in the business layer, but these objects are represented differently in your data layer for performance reasons. But all of this is really not things you should worry about at this point. Just understand that as your applications become more complex, you may have the need to do things differently.
You need to have a look on Onion Architecture. It is a bit out of date in terms of MVC versions, but the tiers are layered greatly.
In terms of IoC container I'd recommend looking on Autofac - easy to use with a lot of features, like registration by conventions and multi-tenant.
As for your questions:
What I usually have is on form submit, controller would get a StudentViewModel submitted, then I would convert it to a Student object and hand over to IStudentRepository that is injected into the controller. And IStudentRepositry will save it to the DBContext. The repository interface would sit in Domain layer, but implementation of the repository would be in Data layer. And DI container will match one to the other.
The trick here is to have all interfaces in Domain layer and implementations sitting wherever they should be. And Domain layer should not be dependent on any other layer (read Domain project would not have reference to Data and Web projects). But Web would depend on Data and Domain layers. You only need Data layer dependency in Web layer to configure IoC container, as web layer is your aggregate root, and IoC should be configured there. But you should never use Data objects directly in any of the operations, you should be injecting interfaces for repositories or services.
There is a lot have been said about the layered architecture, so start with Onion Architecture first, then you'll have a better idea of what you need.