How to organize a project into three tiers? - asp.net

I have an asp.net website and I would like to organize it into three layers
DataAccess
Domain
UI
What specifically goes in each of these layers?
e.g
Data
- Models
- Repositories? Would that be just interfaces
- IoC?
Domain
- Services?
UI
- javascript
- Area specific models?
- css
Could someone provide a simple guideline for organizing an asp.net website like this?

As other people have said each situation is different, but for a basic architecture, I would probably go along with something like this. It has gotten me out of a few jams and up and running quite quickly.
Infrastructure Layer
This is where all the data access is done. Database connection management, etc.
The Repositories include all queries to the database.
The Dependency Resolution sits here too. Use your DI Container of choice.
Domain Layer
This is where all you business logic sits.
The Domain Services Interfaces are what the UI layer call to use your business logic
UI
Pretty obvious this one....
Code Example
--UI
public class MyController
{
private readonly IMySerivce _myService;
public MyController(IMySerivce myService)
{
_mySerivce = myService;
}
public void MyAction()
{
_myService.DoSomeAction();
}
}
--Domain
public Interface IMyService()
{
void DoSomeAction();
}
public class MySerivce : IMyService()
{
private readonly IMyRepository _myRespository;
public MySerivce(IMyRepository myRepository)
{
_myRepository = myRepository;
}
public void DoSomeAction()
{
_myRepository.Save();
}
}
public interface IMyRepository
{
void Save();
}
--DataLayer
public MyRepository : IMyRepository
{
public void Save()
{
//Manage Save here
}
}
Additionally I usually have a separate area for unit/integration tests.
Update
This most definitely is dependent on your situation. It is very hard to say what method is best without fully understanding what you are ultimately trying to build.
From the list below you can see which method works well for you or fits well with your architecture.
Regardless of which one you choose, your Repository Implementation will have to have a dependency on your Domain Objects project.
Some techniques in doing it include:
No Mapping
Your Domain Objects really then become dummy mappings to your tables. i.e. have a table in your database call User. Then have a Domain Object called User. This is by far the simplest technique.
--Domain
public class User
{
public int Id {get; set;}
public string UserName {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string Password {get; set;}
}
--Infrastructure
public class UserRepository : IUserRepository
{
public Core.User GetById(int id)
{
return DBConnection.GetByIdQuery(id);
}
}
Mapping
Martin Fowler describes it here
It is possible in your infrastructure layer to have what are known as Domain Transfer Objects (DTO) that represent your database tables. Similar to above, a table called User, a DTO called User. Both having the same properties.
Your domain Entity then becomes a true representation of your domain and business logic.
The mapping of the DTO to your Domain Entity (search query) can be done in the Repository and the mapping of your Domain Entity to your DTO (save/update query) would also be done in your Repository.
To do your mapping you can either create custom mapping classes or use 3rd party tools like AutoMapper. I am a big fan of AutoMapper.
A sample code example would be along the lines of:
--Custom mapper
public class UserRepository : IUserRepository
{
private readonly IUserMapper _userMapper;
public UserRepository(IUserMapper userMapper)
{
_userMapper = userMapper;
}
public Domain.User GetUserById(int id)
{
var DtoUser = GetUserByIdQuery(int id);
return _userMapper.MapUserDTOToDomainEntity(DtoUser);
}
}
public class UserMapper : IUserMapper
{
public Domain.User MapUserDTOToDomainEntity(DataEntity.User dtoUser)
{
//Manual property mapping
}
}
--AutoMapper Example
public class UserRepository : IUserRepository
{
public Domain.User GetUserById(int id)
{
var DtoUser = GetUserByIdQuery(int id);
return Mapper.Map<Domain.User>(DtoUser);
}
}
Other examples include:
https://stackoverflow.com/questions/14724612
There are many many debates out there in blogs and here on SO about the value of DTO's,
including MSDN, this blog and these https://stackoverflow.com/questions/11237946, https://stackoverflow.com/questions/15148866

Related

Unit of work pattern not allowing me to create db context without options

I am using ef core and I am trying to implement the repository pattern as part of best practices. But I am we bit confused on the context normally I would create the context in the and inject
HomeController(WarehouseDBContext _context)
I have created my unitOfWork Class as suggested by the docs here
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application#creating-the-unit-of-work-class
However I am tad confused. It's expecting options here which is normally handled on the controller.
My UnitOfWork class
public class WarehouseUnitOfWork : IDisposable
{
private WarehouseDBContext context = new WarehouseDBContext();
private WarehouseRepository<StockItem> stockRepository;
public WarehouseRepository<StockItem> StockRepoistry
{
get
{
if (this.stockRepository == null)
{
this.stockRepository = new WarehouseRepository<StockItem>(context);
}
return stockRepository;
}
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
But here it is complain that it expect options which would I presume contain the connection string. I am trying to decouple my code from EF so that If I want to upgrade in the future will be easier. My WareshouseDBContext is describe below
As you can see it is expecting options. What should I pass through here?
namespace WareHouseDal.Dal {
public class WarehouseDBContext : IdentityDbContext<ApplicationUser> {
public WarehouseDBContext(DbContextOptions<WarehouseDBContext> options)
: base(options) {
}
public DbSet<WarehouseCrm> Warehouse { get; set; }
public DbSet<Company> Companies { get; set; }
}
}
When I used to create my context before I just used the singleton pattern of
private readonly WarehouseDBContext _context;
Is their something else I need to do to allow it to accept the creation of the context on the unit of work level.
Error being given is
You shouldn't create a DbContext manually. Why not injecting the DbContext in your UOW class? Then the DI will manage the life cycle of the db context. To be honest I am not a fan of adding a UOW wrapper around EF which already implements the UOW pattern.
I would recommend you to see both talks, it will change the way you structure apps forever:
https://www.youtube.com/watch?v=5OtUm1BLmG0&ab_channel=NDCConferences
https://www.youtube.com/watch?v=5kOzZz2vj2o&t=3s&ab_channel=NDCConferences
Another amazing talk about EF Core details: https://www.youtube.com/watch?v=zySHbwl5IeU&ab_channel=NDCConferences
If you want to stick with Repository pattern, please check Ardalis repository with a clear example: https://github.com/ardalis/CleanArchitecture
I agree Ardalis repository is a great tutorial/example, in case if anyone want a lite solution to implement the Repository and Unit of Work Patterns in EF 5/EF 6.
you may check out the below one, I tested it would work in EF Core 6
https://pradeepl.com/blog/repository-and-unit-of-work-pattern-asp-net-core-3-1/

UnitOfWork + Repository Pattern

I have a very strange situation. I have a UOW Repository pattern. I have domain layer which houses my entities, A Data Access layer which contains the dbcontext (UnitofWork) and repositories for different entities. I have an application layer where i have services which i call for reading and writing data. Architecture contains basically this with some DTOs to help consistency in data. I have a UI layer with MVC5 where i have injected all the dependencies through Unity and it works great if i instantiate each service from a controller constructer.
I have quiet a few services such as GlobalAppSvc (Implemented from IGlobalAppSvc), SystemSettingAppSvc (ISystemSettingAppSvc) etc etc. To make life easier I've created a class called ApplicationManager like this.
public class ApplicationManager
{
public ApplicationManager(ISystemSettingAppSvc systemSettingAppSvc, IBalanceAppSvc balanceAppSvc, IGlobalAppSvc globalAppSvc, IProfileAppSvc profileAppSvc)
{
SystemSettingAppSvc = systemSettingAppSvc;
BalanceAppSvc = balanceAppSvc;
GlobalAppSvc = globalAppSvc;
ProfileAppSvc = profileAppSvc;
}
public ISystemSettingAppSvc SystemSettingAppSvc { get; set; }
public IBalanceAppSvc BalanceAppSvc { get; set; }
public IGlobalAppSvc GlobalAppSvc { get; set; }
public IProfileAppSvc ProfileAppSvc { get; set; }
}
In my Unity i have Registered all the Services and Repositories along with the Unit of Work
container.RegisterType<IUnitOfWork, WUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor());
container.RegisterType<IWUnitOfWork, WUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor());
I have created a BaseController by extending Controller so that i don't have to resolve Application manager in every controller i write. In base controller i am resolving this ApplicationManager as
public class BaseController : Controller
{
// GET: Base
public ApplicationManager ApplicationManager
{
get;
private set;
}
public BaseController()
{
ApplicationManager = UnityConfig.Container
.Resolve<ApplicationManager>();
}
}
I can then go in any controller and extend the controller with this BaseController and i have access to ApplicationManager.GlobalAppSvc.Methods()...
My problem is that whenever there is a data modification such as lets say there is an action which executes to deduct the balance and save changes for a particular user. When i request the user's balance again it is still showing unchanged balance however the balance in Database is deducted but the service is not fetching the updated data. What am i doing wrong?
It looks like the solution is to ensure the BalanceAppSvc needs to be registered with Unity as such:
ApplicationManager=UnityConfig.Container.Resolve<ApplicationManager>(); and registering types as container.RegisterType<IBalanceAppSvc, BalanceAppSvc>(new PerResolveLifetimeManager());

Right architechture for loose coupling with Ninject, ASP.NET MVC 5

I'd appreciate if someone could give an advice on building the right architecture for ASP.NET MVC web app.
I'm currency working on MVC 5 web application, with ADO.NET Entity Data Model which uses existing database. The application mainly uses CRUD operations.
I've doubts on the design pattern I'm trying to use in order to reach loose coupling. I'd also like to use Ninject dependency injector.
So, my solution includes 3 projects: Abstractions, MVCWebApplication and DAL.
I'd like to get a suggestions on structuring the Abstractions project.
Firstly, I've defined the view models for my db entities. I don't use Adapter pattern, instead I'll use AutoMapper to map DB and View model classes:
namespace MVCWebApplication.Models
{
public class CustomerVM
{
public int ID {get; set;}
public string Name {get; set;}
public Contract Contract {get; set;}
}
public class ContractVM
{
public string ContractNo {get; set;} //ID
pulic DateTime AgreementDate {get; set;}
}
}
Generic repository
namespace Abstractions
{
public interface IRepository<T>
{
T Find(object pk);
IQueryable<T> GetAll();
void Insert(T entity);
//...
}
public class Repository<T> : IRepository<T> where T : class
{
public DbContext context;
public DbSet<T> dbset;
public Repository(DbContext context)
{
this.context = context;
dbset = context.Set<T>();
}
//implementation
}
}
And UnitOfWork which gives me an access to the repositories:
namespace Abstractions
{
public interface IUnitOfWork : IDisposable
{
IRepository<Customer> CustomerRepository { get; } //Customer is DB entity
IRepository<Contract> ContractRepository { get; } //Contractis DB entity
//other repositories
void Save();
}
public partial class UnitOfWork : IUnitOfWork
{
private IRepository<Customer> _customerRepository;
private IRepository<Contract> _contractRepository;
private CREntities _context;
public UnitOfWork()
{
_context = new CREntities();
}
public IRepository<Customer> CustomerRepository
{
get
{
if (_customerRepository == null)
_customerRepository = new Repository<Customer>(_context);
return _customerRepository;
}
}
//other repositories, save & dispose ..
}
}
In App_Start I've got:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
}
So, my question is this approach expedient? What is the sense of Ninject here?
Thanks a lot
My view on your approach, its nice and there are many people around using it in big applications. So do not worry.
One suggestion, in your above code, you can use IRepository directly instead of using UnitOfWork.XXXRepository. You got generic repository, it will work with any entity (customer, contract, or a new entity)
With having UnitOfWork class the problem is, when you need another repository (for a new entity), you will need to change UnitOfWork class (breaks Open Close Principle).
What is the sense of Ninject here?
I am not sure if I understand your question fully, Ninject is allowing you to set up your dependencies at one single place and then at runtime injecting these dependencies in your controller or services or wherever used.

Entity Framework & RIA Services - CRUD on Link Table

After many hours, countless failures, I decided to change my Entity Model to include a link table in the model for each many-to-many relationship. This worked for me because RIA Services doesn't support many-to-many relationships.
Regardless, I'm able to build, but do not have any idea how to manage these relationships within the application itself. Should I create methods on the Domain Service, that are hidden from the client and used to perform CRUD operations on the link table objects?
An example would be greatly appreciated, thanks in advance.
I guess you already know http://m2m4ria.codeplex.com/ that adds many to many support to wcf ria services, however if you want to manage it by yourself, you better send it to the client and treat them like any other entities. You will not have Entity A with a collection of B entities and entities B with a collection of A entitities but rather:
public class A
{
int Id {get; set;}
ICollection<A_To_B> B_Entities {get; private set;}
}
public class A_To_B
{
int Id {get; set;}
A EntityA {get; set;}
int id_A {get; set;}
B EntityB {get; set;}
int id_B {get; set;}
}
public class B
{
int Id {get; set;}
ICollection<A_To_B> A_Entities {get; private set;}
}
in your domain service add methods to correctly expose all of these entities and don't forget to properly decorate them (relationship is straight 1:m)
This is indeed a nuisance.
I've not tried m2m4ria and do it manually on the client, ie. I expose the bridge table in the domain service. Sometimes it turns out to be a good idea anyway if the bridge table is later elevated to carry more data.
To ease the pain of managing the bridge table on the client I've written some helper you might want to consider yourself.
public interface ILinkEntity
where LinkEntity : Entity, ILinkEntity
where SourceEntity : Entity, ILinkedSourceEntity
where TargetEntity : Entity
{
SourceEntity Source { get; set; }
TargetEntity Target { get; set; }
}
public interface ILinkedSourceEntity
where SourceEntity : Entity, ILinkedSourceEntity
where LinkEntity : Entity, ILinkEntity
where TargetEntity : Entity
{
EntityCollection Links { get; }
ObservableCollection Targets { get; set; }
}
public static class ManyToManyHelper
{
public static void UpdateLinks(this ILinkedSourceEntity source, EntitySet set)
where SourceEntity : Entity, ILinkedSourceEntity
where LinkEntity : Entity, ILinkEntity, new()
where TargetEntity : Entity
{
if (!(source is SourceEntity)) throw new Exception("Expected source to be a SourceEntity.");
var toAdd = (
from target in source.Targets
where source.Links.FirstOrDefault(le => le.Target.Equals(target)) == null
select target
).ToArray();
foreach (var target in toAdd) source.Links.Add(new LinkEntity() { Source = source as SourceEntity, Target = target });
var toRemove = (
from link in source.Links
where source.Targets.FirstOrDefault(te => te.Equals(link.Target)) == null
select link
).ToArray();
foreach (var link in toRemove)
{
source.Links.Remove(link);
// This can happen when the entities had not yet been added to the context.
set.Remove(link);
}
}
public static void UpdateTargets(this ILinkedSourceEntity source)
where SourceEntity : Entity, ILinkedSourceEntity
where LinkEntity : Entity, ILinkEntity, new()
where TargetEntity : Entity
{
if (source.Targets == null)
{
source.Targets = new ObservableCollection();
}
else
{
source.Targets.Clear();
}
foreach (var link in source.Links) source.Targets.Add(link.Target);
}
}
I have this in a file called ManyToManyUtils and it should live somewhere where your domain entities can reference them (so typically in the domain client project).
I then augment the respective auto-generated domain entities to support those interfaces, eg. like this:
public partial class Question : ILinkedSourceEntity
{
EntityCollection ILinkedSourceEntity.Links
{
get { return QuestionCategories; }
}
public ObservableCollection Categories { get; set; }
ObservableCollection ILinkedSourceEntity.Targets
{
get { return Categories; }
set { Categories = value; }
}
}
public partial class QuestionCategory : ILinkEntity
{
Question ILinkEntity.Source { get { return Question; } set { Question = value; } }
Category ILinkEntity.Target { get { return Category; } set { Category = value; } }
}
public partial class Category
{
}
So in this example each Question can be in many categories. Category as a domain entity needs not to be modified.
I usually augment domain entity classes with properties frequently anyway, so I often already have those partial classes.
Now I can bind views against those new collection properties. However, I still need to call the helper update methods to sync the bridge table with those helper collection properties.
So after each load or refresh from the domain services you have to call:
myQuestion.UpdateTargets();
And after each edit by the user (eg from a SelectionChanged handler in the view, or - if you are happy with the consequences - just before you call SaveChanges), call:
myQuestion.UpdateLinks(myContext.QuestionCategories);
That way, the nastiness is factored out as much as possible.

Proper way of using Unit of Work with unity injection

I am using unity, entity framework 4 with POCO classes, repository pattern for DAL and services for Business Logic control.
I also want to use Unit of Work so I can package together CRUD operations which I perform on different services and then commit them all together.
My question is what would be the proper way to inject the Unit Of Work mechanism into my application using Microsoft Unity?
I understand that I can put the IUnitOfWork together with the repository on the constructor of the proper service and then if Unity mapping is specified it would auto initiate the proper instances, but this way I do not pass the global unit of work but rather create a new instance on each level, which can't be a smart way to do it (actually the repository is initiated even before the service).
What am I missing? (Attached is constructor code as I wrote it now of service and its repository).
U also understand that I can use Unity's ParameterOverrides method to take some global instance of Unit of Work (lets say from my aspx.cs file) and pass it into the service and then into the repository. But it seems a bit lame. Is this my only option?
Thanks
public class GenericRepository<T> : IUnitOfWorkRepository, IGenericRepository<T> where T : BaseEntity, IAggregateRoot
{
private IUnitOfWork _uow;
/// <summary>
/// Returns the active object context
/// </summary>
private ObjectContext ObjectContext
{
get
{
return ObjectContextManager.GetObjectContext();
}
}
public GenericRepository(IUnitOfWork uow)
{
_uow = uow;
}
//blahhhh...
public void Add(T entity)
{
_uow.RegisterNew(entity, this);
}
public void Delete(T entity)
{
_uow.RegisterRemoved(entity, this);
}
//.....blah blah....
public void PersistCreationOf(IAggregateRoot entity)
{
this.ObjectContext.AddObject(GetEntitySetName(), entity);
}
public void PersistUpdateOf(IAggregateRoot entity)
{
// Do nothing as EF tracks changes
}
public void PersistDeletionOf(IAggregateRoot entity)
{
this.ObjectContext.DeleteObject(entity);
}
}
public class CategoryRepository : GenericRepository<XComSolutions.FB.Domain.Model.Entities.Category>, ICategoryRepository
{
public CategoryRepository(IUnitOfWork uow)
: base(uow)
{ }
}
public class CategoryService : ICategoryService
{
public int myID {get; set;}
private ICategoryRepository _categoryRepository;
private IUnitOfWork _uow;
public CategoryService(ICategoryRepository categoryRepository,
IUnitOfWork uow)
{
_categoryRepository = categoryRepository;
_uow = uow;
}
public List<Category> GetAll()
{
return _categoryRepository.GetAll();
}
}
Define an IUnitOfWorkFactory and inject that in your services:
public class Service
{
private readonly IUnitOfWorkFactory factory;
public Service(IUnitOfWorkFactory factory)
{
this.factory = factory;
}
public void DoOperation()
{
using (UnitOfWork context = this.factory.CreateNew())
{
this.DoSomeStuff(context);
this.DoMoreStuff(context);
context.SubmitChanges();
}
}
}
What I think you need to do is to define unit of work factory. You register this factory with your DI container and you resolve for this factory every time you need your unit of work. Then you get unit of work from the factory, work with it and let it go. You often will see that you need your unit of work within a scope of single method or single class. This article discuss Unit of Work pattern in connection with Entity Framework: http://msdn.microsoft.com/en-us/magazine/dd882510.aspx

Resources