DataAccessLayer and organize solution - c#

I have a MVC solution :
In my different file :
Library.DataAccessLayer.LibraryContext.cs :
namespace Library.DataAccessLayer
{
public class LibraryContext : DbContext
{
public LibraryContext() : base("DefaultConnection")
{
}
public DbSet<Book> Books { get; set; }
public DbSet<Author> Authors { get; set; }
}
}
Library.DataAccessLayer.Models.Author.cs :
namespace Library.DataAccessLayer.Models
{
public class Author
{
[Key]
public int AuthorID { get; set; }
[Required]
[StringLength(50)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
.........
}
}
Library.DataAccessLayer.Repositories.AuthorRepository.cs :
namespace Library.DataAccessLayer.Repositories
{
public class AuthorRepository : IDisposable, IAuthorRepository
{
private LibraryContext context;
public AuthorRepository(LibraryContext context)
{
this.context = context;
}
public IEnumerable<Author> GetAuthors()
{
return context.Authors.ToList();
}
public Author GetAuthorById(int id)
{
return .........
}
............
}
}
And in Library.Controllers.AuthorController :
namespace Library.Controllers
{
public class AuthorController : Controller
{
private IAuthorRepository authorRepository;
public AuthorController()
{
this.authorRepository = new AuthorRepository(new LibraryContext());
}
public ActionResult Index()
{
var authors = authorRepository.GetAuthors();
return View(authors);
}
}
}
1/ This architecture is coherent ?
2/ Is it really useful to declare interfaces for my repositories which are implemented in my repository classes ?
3/ In my AuthorRepository, the declaration and call of the LibraryContext is correct?
4/ In my AuthorController, my declaration and call of AuthorRepository is correct ?
5/ In which folder can we put the file LibraryContext ? (If necessary and useful)
6/ Is it good to group repositories interfaces and repositories class in the same folder? If not, how to separate and name the various folders ?
7/ How to improve that?
I need your advices.
Thanks

I find the architecture simple, which is good, maybe as your application grows you'll need more layers
Yeah, is really good, specially if you are going to use dependency injection, which leads to the next questions.
Your implementation is right, as for dependencies you should use some design patterns as, again, dependency injection or factory. All your dependencies should be instantiated outside.
This one should be the same as the previous one, the repository should be instantiated outside.
The structure is supposed to accommodate your needs, but I find the example in here pretty useful
Many developers do it that way, some also, and some others, like me, keep them in separate files, personally I create a 'contracts' folder alongside my repositories and keep the interfaces there.
The best way to find a convention that accommodates you is reading code from other developers, there you will find many styles, structures, architecture and pattern implementations.
I hope you find this useful, May the force be with you

This question is more fit to Codereview website, but I think it deserves an answer here:
Repositories are fine, but you should also consider defining a service layer. Services are responsible for aggregating information using repositories and providing this information using service models. Sending back data models (e.g. Authors) might lead to trouble because:
serialization can fail if navigation properties create cycles
you want to provide more information that is not related to data layer (e.g. some computed stuff)
Example:
class AuthorServiceModel
{
int AuthorId { get; set; }
string FirstName { get; set; }
// ...
}
class LibraryService : ILibraryService // if DI is used
{
public AuthorServiceModel GetAuthorById(int id)
{
// error handling/logging may be put here, if an invalid id is provided
var author = context.Authors.Get(id);
// auto mapping can be used to avoid the typing - check http://automapper.org/
var sm = new AuthorServiceModel { AuthorId = author.AuthorId, FirstName = author.FirstName };
return sm;
}
//
}
The controller will never have to know about your data access layer
2) Repositories unification - if most of your repositories are doing just the standard operations (get all, get by identifier, update entity, remove entity etc.), you may define a generic typed repository that helps you to avoid the repetition:
class Repository<T> : IRepository<T>
{
private LibraryContext context;
public IQueryable<T> All => context.Set<T>().AsQueryable();
public IQueryable<T> AllNoTracking => context.Set<T>().AsNoTracking();
public T Get(int id)
{
return context.Set<T>().Find(id);
}
// other methods
}
3) Implementing interfaces can be useful when using Dependency Injection - DI (e.g. Ninject). This removes some coupling between your classes and also allows automatic testing (bindings can be changed to mock objects). E.g.:
public class LibraryContext : DbContext, ILibraryContext
{
public LibraryContext() : base("DefaultConnection")
{
}
// other methods here
}
public class AuthorRepository : IDisposable, IAuthorRepository
{
private ILibraryContext context;
// the context will be injected and should not be provided by the caller, if DI is used
public AuthorRepository(ILibraryContext context)
{
this.context = context;
}
// other methods come here
}
public class AuthorController : Controller
{
// this allows for automatic injection based on defined bindings
[Inject]
public IAuthorRepository authorRepository { get; set; }
public AuthorController()
{
// no need for this, as DI takes care of the initialization
// also, controller does not have to know about your data access classes
// this.authorRepository = new AuthorRepository(new LibraryContext());
}
public ActionResult Index()
{
var authors = authorRepository.GetAuthors();
return View(authors);
}
}
4) Grouping of files is a matter of taste, but I usually recommend groping them semantically (all classes and interfaces that do similar jobs in a folder). Also, data context and repositories are quite coupled and they can reside in the same project/assembly.
Also, services can be separated in their own project/assembly.
NOTE: For a more thorough analysis, consider providing all the code related to your patterns and post your question on Codereview (they deal with complete and working code, not just fragments). It is a great chance that someone will cover all the topics from naming to the patterns).

Related

how to map model class to infrastructure using the clean architecture

I have confusion about clean architecture, in my project i have two projects one is Infrastructure where i create database and model entities,i have Core project where i created my interfaces and my models,the interfaces inside core are implemnted inside the infrastructure,for example in my Core project i have IDataHandler class,i put i all the signiture which interact with DB,and i implement those signitures inside DataHandler which is in Infrastructure project..now here is my question,
in my Core IDataHandler looks:
public interface IDataHandler
{
public Task<StudentsModel> GetStudent(string id);
}
in my Infrastructure i have StudensEntity which is the exact copy of the StudentModel,but when i want to implemet the IDataHandler i cant use like this:
public interface DataHandler:IDataHanlder
{
public Task<StudentsEntity> GetStudent(string id);
}
it the return type is not the same as its interface,even thought they have the same properties,i ope you understand what im trying ask,if so,what should i do?
The solution you came up with reflects clean architecture principles, especially in regard to the separation between repository interfaces (IDataHandler) and repository implementations (DataHandler) and between what you refer to as "models" (StudentModel) and "model entities" (StudentEntity).
in my Infrastructure i have StudensEntity which is the exact copy of the StudentModel
In order to make this work, the core model should actually be either an abstract class or an interface, e.g. interface IStudent instead of class StudentModel, and infrastructure model StudentEntity should implement that interface. This may lead to such (simplified) code:
// Core (domain language)
public interface IStudent
{
long Id { get; }
string Name { get; }
}
// Infrastructure
public StudentEntity : IStudent
{
public StudentEntity(long id, string name)
{
this.Id = id;
this.Name = name;
}
public long Id { get; }
public string Name { get; }
}
// Core (domain language)
public interface IDataHandler
{
Task<IStudent> GetStudent(string id);
}
// Infrastructure
public class DataHandler : IDataHanlder
{
public async Task<IStudent> GetStudent(string id)
{
// Construct StudentEntity from database and return it.
}
}

ASP.NET Boilerplate - "The ObjectContext instance has been disposed" exception

I'm trying to use ASP.NET Boilerplate to handle my project and I have one serious problem.
I have 2 Models : Photo and Comment:
public class Comment : Entity<int>
{
[DataType(DataType.MultilineText)]
public string Text { get; set; }
public string Author { get; set; }
public int ItemID { get; set; }
public virtual Item Item { get; set; }
}
public class Item : Entity<int>
{
public string Title { get; set; }
public string Description { get; set; }
public ItemSourceType SourceType { get; set; }
public byte[] PhotoBytes { get; set; }
public string Url { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
Additionally I have created default OOB repository based on RepositoryBase<Item> and same for Comment.
The problem exists when I'm trying to get Item like this:
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Item item = _repoItems.Get(id.Value);
if (item == null)
{
return HttpNotFound();
}
return View(item);
}
When I'm debugging this code I can see that item has this exception in Comments property.
Am I missing something from ASP.NET Boilerplate or what?
Thanks for helping!
//Edit:
Full exception message:
{"The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."}
I just stumbled across the same problem.
Seems to be that the UnitOfWork implementation creates and disposes a new DbContext for each "UnitOfWork"
So to fix that particular problem, try to inject "IUnitOfWorkManager"
and call
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
using(var uow = _unitOfWorkManager.Begin())
{
try
{
Item item = _repoItems.Get(id.Value);
if (item == null)
{
return HttpNotFound();
}
return View(item);
}
finally
{
uow.Complete()
};
}
}
if that works, consider calling "Begin()" in the constructor of your ApiController and "Complete()" in its "Dispose()" override.
Hope that helps!
No. The problem is most likely in your repository, the code of which you unfortunately have not included. If I had to guess, I'd say you're using something like the following in that repository method:
using (var context = new ApplicationContext())
{
// fetch something
}
Your Comments property is virtual, which means by default, Entity Framework will lazy load it, only actually issuing the query for that to the database once you try to access the property. However, by that point, you context has been disposed because the repository method has already finished its work, and your context was only available inside the using block.
There's a number of ways to fix this. You could eagerly load comments inside the the using block:
return context.Items.Include("Comments").Find(id);
However, that really just glosses over the problem. The best thing you can do is just not use using. Ideally, your context should be instantiated once and only once for each request. The easiest way to do that is to use a dependency injection container and add a constructor to your repository that accepts the context:
public class MyAwesomeRepository
{
private readonly ApplicationContext context;
public MyAwesomeRepository(ApplicationContext context)
{
this.context = context;
}
}
The configuration for your DI container will vary depending on which you choose to go with, but generally, you want to make sure that you bind your context class to request scope.
I had the similar issue with ASP.NET Boilerplate and figured out that this framework does all this DI magic properly only if you name your interfaces and classes in accordance with their naming conventions. You can somehow do it manually though, but you have to drill down into ABP architecture much deeper than you want.
A link posted by #ChrisPratt (see comments in his answer) says:
Naming conventions are very important here. For example you can change name of PersonAppService to MyPersonAppService or another name which contains 'PersonAppService' postfix since the IPersonAppService has this postfix. But you can not name your service as PeopleService. If you do it, it's not registered for IPersonAppService automatically (It's registered to DI framework but with self-registration, not with interface), so, you should manually register it if you want.
In my case, I had a service called ProductService implementing interface IProductAppService. It failed for me with ObjectDisposedException exception until I renamed my service to ProductAppService.
I don't think that OP still have this issue, but hopefully it will save few hours for the folks struggling with ABP like me. :-)

Successfully implementing custom UserManager<IUser> in Identity 2.0

I'm trying to navigate the black hole that is the custom implementation of Identity Membership. My goal right now is simply to get this line from my ApiController to correctly retrieve my UserManager:
public IHttpActionResult Index()
{
var manager = HttpContext.Current.GetOwinContext().GetUserManager<UserManager<MyUser,int>>();
//manager is null
}
Here's my setup. In my Startup's Configuration I set up the WebApi and add my OwinContext:
app.CreatePerOwinContext<UserManager<MyUser,int>>(Create);
My Create method:
public static UserManager<User,int> Create(IdentityFactoryOptions<UserManager<MyUser,int>> options, IOwinContext context)
{
return new UserManager<MyUser,int>(new UserStore(new DbContext()));
}
the rest is the most basic implementation I can make.
MyUser:
public class MyUser : IUser<int>
{
public int Id { get; set; }
public string UserName { get; set; }
}
MyUserStore:
public class MyUserStore : IUserStore<MyUser,int>
{
private IdentityDbContext context;
public MyUserStore(IdentityDbContext c)
{
context = c;
}
//Create,Delete, etc implementations
}
MyDbContext:
public class MyDbContext : IdentityDbContext
{
public MyDbContext() : base("Conn")
{
}
}
This is all for the sake of learning how Identity works, which I'm pretty convinced no one actually knows. I want to be able to fully customize my Users and Roles eventually, avoiding Microsoft's IdentityUser.
Again, my issue right now is that in my controller, I am getting null when trying to retrieve my UserManager.
Any and all help is greatly appreciated.
I had several errors, but the main one was that my Startup class looked like :
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseWebApi(new WebApiConfig());
app.CreatePerOwinContext(MyDbContext.Create);
app.CreatePerOwinContext<MyUserManager>(MyUserManager.Create);
}
}
Of course, the OWIN pipeline will plug my dependencies after firing off the WebAPI calls. Switching those around was my main problem.
In addition, I finally found this great guide way down in my Google search. It answers pretty much everything I was getting at. I needed to implement a concrete class that was a UserManager<MyUser,int>
I hope this is able to help someone later on.
Are you using MyIdentity.User or MyIdentity.MyUser? You have two different objects passed into the TUser parameter in your examples.
I tested your implementation and did not have issues retrieving the registered instance of the UserManager.
To fully customize your Users and Roles, you will need to end up writing a new implementation of the UserManager in order to get your Authentication, Claims, Roles, method calls, etc to work.
If you are trying to learn how Identity works, I would suggest working with the default implementation of UserManager and IdentityUser. Get that to work first.
Here is a good tutorial
Eventually, create your own users implementing IdentityUser. All of the UserManager functions will work and you will have access to your new properties. The additional properties will automatically be built into the AspnetUser table generated by the IdentityDbContext.
public MyIdentityUser : IdentityUser
{
public int Id {get; set;}
public string CustomUserId {get; set;}
public string UserId { get; set; }
}
Or you can start building your custom MyIdentityUser with foreign key references to other objects.
public MyIdentityUser : IdentityUser
{
public virtual UserProperties Properties { get; set; }
}
Does this help any?

Passing DTO to my ViewModels constructor to map properties

In my solution I have two projects.
Project 1 (Core)
Mapping SQL to DTO using Dapper
Project 2 (WebUI - ASP.NET MVC 4)
Here I use a ViewModel per View.
Examples of a Controller
[HttpGet]
public ActionResult Edit(int id)
{
// Get my ProductDto in Core
var product = Using<ProductService>().Single(id);
var vm = new ProductFormModel(product);
return View(vm);
}
Examples of a ViewModel
public class ProductFormModel : BaseViewModel, ICreateProductCommand
{
public int ProductId { get; set; }
public int ProductGroupId { get; set; }
public string ArtNo { get; set; }
public bool IsDefault { get; set; }
public string Description { get; set; }
public string Specification { get; set; }
public string Unit { get; set; }
public string Account { get; set; }
public decimal NetPrice { get; set; }
public ProductFormModel(int productGroupId)
{
this.ProductGroupId = productGroupId;
}
public ProductFormModel(ProductDto dto)
{
this.ProductId = dto.ProductId;
this.ProductGroupId = dto.ProductGroupId;
this.ArtNo = dto.ArtNo;
this.IsDefault = dto.IsDefault;
this.Description = dto.Description;
this.Specification = dto.Specification;
this.Unit = dto.Unit;
this.Account = dto.Account;
this.NetPrice = dto.NetPrice;
}
public ProductFormModel()
{
}
}
Explanation:
I'll get my DTOs in my controller using a service class in the project (Core).
Then i create my ViewModel and pass the DTO to the constructor in ViewModel.
I can also use this view to add a new Product because my ViewModel can take a empty constructor.
Does anyone have experience of this. I wonder if I am in this way will have problems in the future as the project gets bigger?
I know this has nothing to do with Dapper. But I would still like a good way to explain my solution.
I think you will be fine using your current approach. More importantly, start out like this and refactor if you start to encounter problems related to your object mapping code (instead of thinking too much about it beforehand).
Another way to organize mapping logic that I use sometimes is to employ extension methods. That way, the mapping code is kept separate from the view model itself. Something like:
public static class ProductMappingExtensions
{
public static ProductFormModel ToViewModel(this ProductDto dto)
{
// Mapping code goes here
}
}
// Usage:
var viewModel = dto.ToViewModel();
Yet another approach would be to use a mapping framework like AutoMapper - this is a good fit in particular if your mapping logic is simple (lots of 1:1 mappings between properties).
But again, start simple and refactor when you need to.
I realize that this is a little bit late answer, but maybe it will help someone in the future.
This way of doing mapping between objects breaks the 'S' of the SOLID principles, because the responsibility of the ViewModel is to prepare data in its properties to be ready to use by the view and nothing else, therefore, mapping objects should not be on it's responsibilities.
Another drawback of this way is that it also breaks the 'Loose Coupling' OO principle as you ViewModel is strongly coupled with your DTO.
I think, even when we are in the very first step of the project, there are some importants OO principles that we should never break, so using mapper classes, either auto (AutoMapper, ValueInjecter ...) or manual, is definitely better.

Interface a DomainContext for WCF RIA Services - is this a good approach?

I want to have an IDataService that I can then swap out with a different service for mocking or use for Design time data. Is this a good approach or am I just creating problems for myself.
public interface INorthwindContext
{
public IDomainContext Context;
}
I've tried using a partial class in my Silverlight project to implement an interface like so:
public partial class NorthwindContext : INorthwindContext
{
}
Now I can create a DataService or TestDataService etc, like so:
public class DataService : IDataService
{
public INorthwindContext Context { get; set; }
}
My INorthwindContext:
EDIT: unless I add all the methods from the DomaincContext to this interface I'm going to lose need functionality to lad the data. I'm also going to have to manually update the interface each time I add new entites to the service.
public interface INorthwindContext
{
EntitySet<Category> Categories { get; }
EntityQuery<Category> GetCategoriesQuery();
EntityQuery<Product> GetProductsQuery();
EntityQuery<Region> GetRegionsQuery();
EntityQuery<Shipper> GetShippersQuery();
EntityQuery<Supplier> GetSuppliersQuery();
EntityQuery<Territory> GetTerritoriesQuery();
EntitySet<Product> Products { get; }
EntitySet<Region> Regions { get; }
EntitySet<Shipper> Shippers { get; }
EntitySet<Supplier> Suppliers { get; }
EntitySet<Territory> Territories { get; }
}
This was very helpful and http://www.nikhilk.net/NET-RIA-Services-ViewModel-Pattern-2.aspx
Here's the pattern I recommend for using RIA Services with MVVM (which is a good pattern to use for mocking and design-time data). It's a take on John Papa's MVVM sample.

Categories