Abstract away the DAL from Entity Framework implementation - c#

First of all I'm sorry if this is going to be a long post, but I don't know how to explain the problem in the correct way without the required details.
I'm having troubles finding a way to abstract my DAL from an Entity Framework implementation. The project I'm working on is very small, but if in future I'd want to switch to another ORM like NHibernate, or just plain ADO.NET, I'd like to write code just for the implementation, not the entire DAL.
Say I have these entities in my MyWallet.DAL:
public interface IWallet {
long Id { get; set; }
float TotalAmountOfMoney { get; set; }
long CurrencyId { get; set; }
ICurrency Currency { get; set; }
DateTime RecordedOn { get; set; }
ICollection<IMoneyMovement> MoneyMovements { get; set; }
}
public interface ICurrency {
long Id { get; set; }
char Symbol { get; set; }
string Code { get; set; }
string Description { get; set; }
}
public interface IMoneyMovement {
long Id { get; set; }
float Amount { get; set; }
string Description { get; set; }
long WalletId { get; set; }
IWallet Wallet { get; set; }
DateTime RecordedOn { get; set; }
DateTime MovedOn { get; set; }
}
As you can see these are plain interfaces which I plan to implement on another library which will contain the actual Entity Framework implementation (say MyWallet.DAL.EntityFramework). Of course I'm going to decorate the entities implementation with Entity Framework specific attributes as [Key] or [ForeignKey] and stuff like that.
I also defined some repository in MyWallet.DAL like IWalletRepository, IMoneyMovementRepository, ICurrencyRepository to gain access to the entities. Actually I don't know if this is the right way to design access to the entities. Of course I also defined factories to get the concrete implementation of the entities.
In my business layer I defined services to handle the object request, work with the DAL entities and return a business object, like this:
public class WalletService {
private readonly IWalletRepository _walletRepository;
private readonly IWalletFactory _walletFactory;
public WalletService(IWalletRepository walletRepository,
IWalletFactory walletFactory) {
_walletRepository = walletRepository;
_walletFactory = walletFactory;
}
public CreatedWallet CreateWallet(CreateWalletRequest request) {
var wallet = _walletFactory.Create();
wallet.CurrencyId = request.CurrencyId;
wallet.TotalAmountOfMoney = request.TotalAmountOfMoney;
wallet.RecordedOn = DateTime.Now;
_walletRepository.Create(wallet);
_walletRepository.SaveChanges();
return new CreatedWallet {
Id = wallet.Id
}
}
}
I thought this was going to work seamlessly, or at worst - in a situation when I've got more than one repository - I could share the DataContext so I'd need to fire the SaveChanges method on just one to reflect the changes on the database.
The problem is with the repository implementation, in this case I'll continue with Entity Framework:
public class EFDataContext : DbContext {
public EFDataContext() : base ("name=MyConnectionString") {
}
public virtual DbSet<EFWallet> Wallets { get; set; }
public virtual DbSet<EFMoneyMovement> MoneyMovements { get; set; }
public virtual DbSet<EFCurrency> Currencies { get; set; }
}
public class EFWalletRepository : IWalletRepository {
private readonly EFDbContext _dataContext;
public EFWalletRepository(EFDbContext dataContext) {
_dataContext = dataContext ?? new EFDbContext();
}
public int SaveChanges() {
return _dataContext.SaveChanges();
}
public void Dispose() {
_dataContext.Dispose();
}
public void Create(IWallet wallet) {
...???
}
}
Now that's the problem: how do I work with interfaces when the DataContext knows only about concrete implementations? Am I doing this all wrong?
UPDATE:
Ok so, basically, as stated out by #TomTom, why fight Entity Framework when you could just embrace its power? I guess I'll just let EF be the abstraction. In fact, by letting EF act as the DAL, you can just focus on the business logic of your project.
And to put it all together and respond to #tdragon regarding the repositories / unit of work issue: yes, I could either wrap multiple repositories inside an unit of work or simply let the DbContext be the unit of work:
public class EFWalletRepository : IWalletRepository {
private readonly EFDbContext _dataContext;
public EFWalletRepository() {
_dataContext = new EFDbContext();
}
public void Dispose() {
_dataContext.Dispose();
}
public IEnumerable<Wallet> Wallets {
get { return _dataContext.Wallets; }
}
public void SaveWallet(Wallet wallet) {
if (wallet.Id == 0) {
_dataContext.Wallets.Add(wallet);
} else {
var databaseEntry = _dataContext.Wallets.Find(wallet.Id);
//update properties
}
_dataContext.SaveChanges();
}
}

Simply speaking: yes, you do it wrong. You introduce a bad abstraction (that costs you dearly in functionality) "because of". EF already is an abstraction.
Any abstraction on top of it will cost you in terms of functionality used - which in terms of databases comes with a big performance impact. Want an example? "Include" to preload navigation properties (instead of lazy loading). You will have to work around this and a lot of more detailed behavior that is ORM specific - for the gain of having what? And if you give up on those higher more specific functions your performance WILL suffer.

I can't see any reason to abstract your model (entities). Do you expect them to change when you change the way you access your database?
But if you want to keep it that way, you can make your repository interfaces generic, and pass the concrete entity type when defining repository, so you would end up with:
public class EFWalletRepository : IWalletRepository<EFWallet>
{
public void Create(EFWallet wallet)
{
_dataContext.Add(wallet);
}
}
Other suggestions:
You should not expose sets for your model properties. It's against OOP rules - you should rather expose some methods to manipulate the objects, the state should be more internal.
You probably should not add SaveChanges() method to your repository - this should be a "unit of work" job to commit all changes to the database.
You would face a problem when you would use more than one repository in your service layer, as you create a new DbContext for repository, when you should have one for single "unit of work".

Related

Where to implement business calculations on a query using Clean architecture

We are re-building our core application trying to use clean architecture and CQRS.
Projects have all been set up.
Currently this is all working
Domain layer currently holds complex models ie. models that simply map to the results from a stored proc.
namespace UHNM.myHotelCore.Domain.Entities.floor
{
public class FloorCx
{
public int FloorId { get; set; }
public int x { get; set; }
public int y { get; set; }
public string FloorCode { get; set; }
public string Floor { get; set; }
}
}
This is all working. We now want to introduce calculations.
We use generally use automapper in our query handler in the application layer to map our complexmodel to our returned DTO.
var floors = _autoMapper.Map<List<FloorDTO>>(_floor.GetFloors(request.FloorId));
Our return model from the API looks like this :-
namespace UHNM.myHotelCore.Application.CQRS.Queries.Floor.DTO
{
public class Floor
{
public int FloorId { get; set; }
public decimal Average { get; set; }
public string FloorCode { get; set; }
public string Floor { get; set; }
}
}
Where average is calculated based on x and y from the complex model.
Using clean architecture, where is generally the best place for these calculations to go? and at what point are they called?
Would they sit within FloorCx?
public class FloorCx
{
public int FloorId { get; set; }
public int x { get; set; }
public int y { get; set; }
public string FloorCode { get; set; }
public string Floor { get; set; }
Public decimalCalculateAverage(int x, int y)
{
//Calculation goes here
}
}
Create a separate class for the calculations?
Or even a separate project for business logic?
From what I understand, your FloorCx is placed in Domain layer. The current shape of that class is a pure anemic model, which is an anti pattern in DDD world.
Not sure if your intention is to follow DDD principles as well, but if it is, then you could introduce repositories that return your FloorCx data models, which then you map to your real business objects. Such business objects should have business behavior, so having calculations inside is a way to go as long as the calculations can be self-contained, meaning they rely on object's internal properties, or accept primitive types (to reduce coupling between your domain model and other resources). When the calculations require more information from the outside world, you can create business services that do them.
Also, in DDD world, AutoMapper and similar solutions are often discouraged, also because your domain objects should not have public setters on their properties, but rather expose constructors or static factory methods that control what is initialized and how, ensuring object's internal consistency.
Having that said, I would create FloorCxDataModel that represents objects fetched from your repository (which abstracts away the stored procedure call and transformations), which then is mapped to a FloorCx business model that exposes methods for calculations and other business behavior. If those calculations depend on external information, for simple types that should work too, but for more complex input parameters I would create a FloorCxCalculationService that resides in Domain layer and does necessary calculations for you.
In the end, you map that business object to your FloorDto (which contains only data, no additional behavior) and return it from your API. In my view, that DTO should also have read-only public properties and have constructor/static factory method that does initialization.

How to implement multiple instances of interface for different subclasses?

I have a large class that used to hold different information for two different sets of the same class. For example, say a receipt that can be a customer receipt or an internal receipt. All this information is in one giant class because that's how the database is structured, but I want to separate the classes so that I would have a receipt class that holds all the shared information, a customer receipt class, and an internal receipt class. They could share an interface, but the implementations would be different, and that is what is confusing me.
Should there be two separate interfaces that get implemented? So I would have an ICustomerReceipt and IInternalReceipt? I thought there should be one interface with say a Get() and Save() method, and based on the implementation if it's a customer or internal receipt, I get the information specific to the class. I'm a bit lost here.
public class Receipt {
public int ID { get; set; }
public int ReceiptNumber { get; set; }
public List<string> Items { get; set; }
}
public class CustomerReceipt : Receipt {
public string CustomerNumber { get; set; }
public string CustomerEmail { get; set; }
public string CustomerOption { get; set; }
}
public class InternalReceipt : Receipt {
public string InternalNumber { get; set; }
public string InternalEmail { get; set; }
public string InternalOption { get; set; }
}
public interface IReceiptRepository {
public Receipt Get(int id);
public Receipt Add(Receipt receipt);
}
public CustomerReceiptRepository : IReceiptRepository {
public CustomerReceipt Get(int id) {
// get information about customer receipts here
}
}
public InternalReceiptRepository: IReceiptRepository {
public InternalReceipt Get(int id) {
// get information about internal receipts here
}
}
Basically I just want to return the correct Receipt to a view model in my controller that just has the generic 'ReceiptNumber' or 'ReceiptEmail'. I know it's not the best example, but it's the only one I could come up with.
Don't get tripped up on trying to force two similar things to share a single abstraction (base class or interface). So, I'd recommend what you suggested: create two separate interfaces.
Remember, the point of polymorphism is so you don't have to know what specific (derived/implemented) type an instance is if you're only looking for an instance of the base type/interface. That's it. If you don't need that, then jumping through hoops to force two similar classes to share a base is not worth it.
public interface IReceiptRepository {
public Receipt Get(int id);
public Receipt Add(Receipt receipt);
}
public CustomerReceiptRepository : IReceiptRepository {
public Receipt Get(int id) {
// get information about customer receipts here
return new CustomerReceipt();
}
}
public InternalReceiptRepository: IReceiptRepository {
public Receipt Get(int id) {
// get information about internal receipts here
return new InternalReceipt();
}
}
Inheritance can be represented on the database in different ways and there are some strategies depending on the ORM you are using.
At the end of the day, using one of the strategies, you can base your repository on the base class and let the ORM act as a proxy to resolve the instance you need, or try to recreate yourself, at the level of the repository, based on a discriminator field, the instances you need
Receipt
ID
ReceiptNumber
CustomerNumber
CustomerEmail
CustomerOption
InternalNumber
InternalEmail
InternalOption
DISCRIMINATOR_FIELD
(most of the ORM do this translation for you), but for you to get the idea, you can keep only one repository to treat all the classes as Receipt and keep your hierarchy as you have it.
public interface IReceiptRepository {
public Receipt Get(int id);
public Receipt Add(Receipt receipt);
}
public CustomerReceiptRepository : IReceiptRepository {
public Receipt Get(int id) {
var rec = DbContext.Table.Receipt.FirstOrDefault(r => r.id = id);
if(rec.DiscriminatorField == 1) //CustomerReceipt
{
return new CustomerReceipt
{
ID = ...
ReceiptNumber = ...
CustomerNumber = ...
CustomerEmail = ...
CustomerOption = ...
}
}
//all other cases are InternalReceipts
return new InternalReceipt
{
ID = ...
ReceiptNumber = ...
InternalNumber = ...
InternalEmail = ...
InternalOption = ...
}
}
}
The same thing for the Add method, just fill only the fields you need for that object. This composition is basing everything on a discriminator field. I am not suggesting you implement your solution in that way, but with that, you still get on your ViewModel the generic receipt. My suggestion is that you read more about the ORM you are using an how you can represent inheritance there(maybe you are using database first instead of code first and you will need to handle the things manually, because the database was not designed on that way and you need to take a similar approach of what I suggested. But if you have the chance to create your POCO classes and create the database, definitely it deserves to take a look at how they implement the inheritance.
Here I am attaching a link of how this problem is addressed on EntityFramework 6
Inheritance Strategy in Entity Framework 6
Hope this helps

Should I transform Entity (Persistent) objects to DTO objects?

My project is layered as follows:-
DAL (Entity) --> BLL (DTO) --> ApplicationComponent (ViewModel).
There will be multiple components of application (ApplicationComponent) which will access BLL. Components include windows services, web services, web API and MVC controller.
I am transforming NHibernate Entity objects to DTO objects while passing them from DAL to BLL. While passing this state to ApplicationComponent, BLL again converts it to ViewModel.
This helps me separate the concerns and how data is handled in each layer. I am not in favor of returning NHibernate Entity object to view for following reasons: -
Data get exposed to UI that I want to hide (or only expose if needed) like passwords, user type, permission etc.
On references/joins, NHibernate executes additional queries when property is accessed which nullify the use of lazy loading.
Unnecessary data exposed to user (of Entity) creates confusion and gap for bugs.
Persistence implementations leaking into BLL/UI. Entity is not designed for UI. It cannot serve UI in all cases.
We use attributes on DTO properties for user input validation which looks odd with Entity.
I am facing following problems with this approach: -
Biggest and obvious problem is redundant objects with similar members and functionality.
I have to write mapper methods in each layer to transform object. This could be minimized by using AutoMapper or something similar; but it does not fully resolve problem.
Questions:-
Is this an over separation and should be avoided (at least minimized)?
If this approach is correct, I do not see any simple way to fully bypass two problems I stated above. Please suggest.
If this approach is incorrect, please suggest corrections.
References:-
Link1 suggests to transfer Entity object to view which in my understanding not a good idea.
Link2 suggests to map Entity with DTO that I am already doing.
Link3 does not help.
Link4 suggests using something like auto mapper tools which is OK. But it still does not solve the problem completely.
Link5 is great post. It explains why those should be separate which I agree. It does not comment on how to minimize the overhead caused by it.
Link6 is not helpful again.
Link7 is an excellent answer which suggests use Entity as is in UI if possible. It still does not apply to most of my project.
Linl8 is another excellent resource that suggest to go on mapping two way as I am doing now. It still does not suggest a way to minimize overhead.
Have you considered creating a shared interface between the DTO and the Entity? You should not tightly couple your ORM to the rest of your application. Or in fact use anything other than interfaces between them if at all possible.
You could, in theory, have a separate project that just holds the contract/abstractions of what you expect to be passed around. To minimize mapping overhead and to leave it open for the extension you can ensure that the entity implements the interface as expected (omitting what is not needed), and in cases where you need a bespoke DTO you can create a model with mapping using the interfaces.
There is some overhead when adding extra interface projects but it will keep your code cleaner and more maintainable in the long run.
namespace Data
{
public class FakeRepo : IFakeRepo
{
public IThisIsAnEntity GetEntity()
{
return new ThisIsAnEntity();
}
}
public class ThisIsAnEntity : IThisIsAnEntity
{
public string HiddenField { get; set; }
public long Id { get; set; }
public string SomeField { get; set; }
public string AnotherField { get; set; }
}
}
namespace Data.Abstractions
{
public interface IFakeRepo
{
IThisIsAnEntity GetEntity();
}
}
namespace Abstractions
{
public interface IThisIsAnEntity : IThisIsAnSlimmedDownEntity
{
string SomeField { get; set; }
}
public interface IThisIsAnSlimmedDownEntity
{
long Id { get; set; }
string AnotherField { get; set; }
}
}
namespace Services.Abstractions
{
public interface ISomeBusinessLogic
{
IThisIsAnEntity GetEntity();
IThisIsAnSlimmedDownEntity GetSlimmedDownEntity();
}
}
namespace Services
{
public class SomeBusinessLogic : ISomeBusinessLogic
{
private readonly IFakeRepo _repo;
public SomeBusinessLogic(IFakeRepo repo)
{
_repo = repo;
}
public IThisIsAnEntity GetEntity()
{
return _repo.GetEntity();
}
public IThisIsAnSlimmedDownEntity GetSlimmedDownEntity()
{
return _repo.GetEntity();
}
}
}
namespace UI
{
public class SomeUi
{
private readonly ISomeBusinessLogic _service;
public SomeUi(ISomeBusinessLogic service)
{
_service = service;
}
public IThisIsAnSlimmedDownEntity GetViewModel()
{
return _service.GetSlimmedDownEntity();
}
public IComposite GetCompositeViewModel()
{
var dto = _service.GetSlimmedDownEntity();
var viewModel = Mapper.Map<IThisIsAnSlimmedDownEntity, IComposite>(dto);
viewModel.SomethingSpecial = "Something else";
return viewModel;
}
}
public class SomeViewModel : IComposite
{
public long Id { get; set; }
public string AnotherField { get; set; }
public string SomethingSpecial { get; set; }
}
}
namespace UI.Abstractions
{
public interface IComposite : IThisIsAnSlimmedDownEntity, ISomeExtraInfo
{
}
public interface ISomeExtraInfo
{
string SomethingSpecial { get; set; }
}
}
nhibernate is one of those orm`s that allow you to avoid having DAL entities and it will be better for performance to avoid extra mapping from BLL TO DAL, but if it is not critical for you, it will be better to keep it at as it is to have application layers loose coupled

Entity Framework entity model's values empty when running constructor

I'm implementing a POCO in my project that represents a row in my database table. I'd like to modify one of the values in the constructor.
Unfortunately, it seems that the values are populated only after the constructor is run, so there's no way for me to perform my required logic. Is this a bug or by design?
I should probably mention that I'm using Code First.
public partial class CheckpointValue
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Column("saljare")]
public int SalesAgentId { get; set; }
[Column("volym")]
public int Value { get; set; }
[Column("datum")]
public DateTime Date { get; set; }
[Column("typ")]
public string Type { get; set; }
public CheckpointValue()
{
// Values empty... Why haven't they been populated when the constructor is run?
}
}
Unfortunately, it seems that the values are populated only after the
constructor is run, so there's no way for me to perform my required
logic. Is this a bug or by design?
This is by design. BTW, how you would be able to get these properties already populated during construction-time without providing constructor arguments?.
Maybe you're trying to implement your logic in the wrong place. If you're looking for implementing business rules, domain validation or who knows what, it should be done in another class. For example, your repository would be a good place to do things before returning the requested object.
public CheckpointValue GetById(Guid id)
{
CheckpointValue checkpointValue = YourDbContext.CheckpointValues.Find(id);
// Implement here what you wanted in your class constructor...
return checkpointValue;
}

POCO's, behavior and Peristance Igorance

From what I have read POCO classes should be persistence ignorant and should not contain references to repositories.
Q1. Given the above, how would I populate the QuestionBlocks collection? I have read that POCO's should contain behavior so you don't end of with an anemic model, so I'm kind of confused as how one is supposed to do that without persistence. If that's the case then what kind of behavior would you put in a POCO?
Ex:
public class Survey
{
public int SurveyId { get; set; }
public string Title { get; set; }
public int BrandId { get; set; }
public DateTime Created { get; set; }
public List<SurveyQuestionBlock> QuestionBlocks { get; set; }
[ResultColumn]
public string Name { get; set; }
/// <summary>
/// Constructor
/// </summary>
public Survey()
{
Created = DateTime.Now;
QuestionBlocks = new List<SurveyQuestionBlock>();
}
}
I would append another view: POCO states for objects which are not dependent on any framework. The wiki definition of a POJO is much more meaningful to me then the one for POCO:
http://en.wikipedia.org/wiki/Plain_Old_Java_Object
To paraphrase the wiki definition of the POJO, we can say that POCO object might not be forced to:
I. Extend prespecified class:
public class MyClass : AnyFramework.ObjectBase {...
II. Implement prespecified interfaces
public class MyClass : AnyFramework.IHaveDependency {...
III. Contain prespecified attribute
[AnyFramework.KeyAttribute]
public class MyClass {...
Given this (almost anything else is allowed) in the meaning of taking care about the object state. Other words, if object will check Business logic, it is correct.
But any POCO object can be used in a framework. Today it is mostly for ORM which is responsible for persistence. All application tiers are working with POCO objects, while data layer is responsible for loading and persisting (CRUD). This is mostly done via Proxies of these POCO objects.
So, POCO could be used as full business object, which can take care about itself (check correctness of collection items, properties...). This makes it different from DTO
Given the above, how would I populate the QuestionBlocks collection?
When reading from a database, the persistence infrastructure should populate the QuestionBlocks collection - reconstitution. Reconstruction should not invoke behavior, it should only set appropriate fields on the POCO. This is the responsibility of the repository. A repository is typically referenced from an application service, which sets up the stage for invoking entity behavior.
If that's the case then what kind of behavior would you put in a POCO?
The behavior in the POCO entity should be concerned with making changes to the entity itself as well as maintaining invariants - ie ensuring the integrity of the entity. In your example, the simplest kind of behavior on the POCO should be method for adding a new question block to the collection on the survey. Ideally, you would make many of the properties on the survey entity read-only:
public class Survey
{
public int SurveyId { get; private set; }
public string Title { get; private set; }
public int BrandId { get; private set; }
public DateTime Created { get; private set; }
public IList<SurveyQuestionBlock> QuestionBlocks { get; private set; }
public string Name { get; private set; }
public void AddQuestionBlock(string questionBlockInfo)
{
this.QuestionBlocks.Add(new SurveyQuestionBlock(...));
}
public Survey()
{
Created = DateTime.Now;
QuestionBlocks = new List<SurveyQuestionBlock>();
}
}
The persistence layer should be able to set the values of the read-only properties via reflection. You can go a step further and only expose the question blocks collection as a read-only collection to ensure that it can only be modified from within the entity itself.

Categories

Resources