Persist Data by Programming Against Interface - c#

I have a IBankAccount interface that I will be passing to the ApplicationService. The changes made on the account objects (in the ApplicationService project) need to be persisted in the database. The repository receives the changes using IBankAccount interface. How can I persist this data into database? This is implemented using LINQ to SQL.
Note: Following is a comment from Scott in http://weblogs.asp.net/scottgu/archive/2007/06/29/linq-to-sql-part-3-querying-our-database.aspx
"Add the interfaces to your LINQ to SQL data model classes. The LINQ to SQL classes are partial classes - which means you could add the interface directly to them."
public class LijosSimpleBankRepository : ILijosBankRepository
{
public System.Data.Linq.DataContext Context
{
get;
set;
}
public virtual void UpdateAccount(DomainInterfaces.IBankAccount iBankAcc)
{
DBML_Project.BankAccount bankAccount;
}
}
namespace DomainInterfaces
{
public interface IBankAccount
{
int BankAccountID { get; set; }
string AccountType { get; set; }
System.Nullable<System.DateTime> OpenedDate { get; set; }
string Status { get; set; }
System.Nullable<int> AccountOwnerID { get; set; }
}
}
namespace DBML_Project
{
public class FixedBankAccount : BankAccount
{
//Note: BankAccount already implemnts IBankAccount
}
public class SavingsBankAccount : BankAccount
{
//Note: BankAccount already implemnts IBankAccount
}
//The auto generated calss is made as abstract
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.BankAccount")]
[InheritanceMapping(Code = "Fixed", Type = typeof(FixedBankAccount), IsDefault = true)]
[InheritanceMapping(Code = "Savings", Type = typeof(SavingsBankAccount))]
public abstract partial class BankAccount : INotifyPropertyChanging, INotifyPropertyChanged, DomainInterfaces.IBankAccount
{
..
}
}
READING
Optimizing Repository’s SubmitChanges Method
How do you abstract out your persistence code when using LINQ to SQL?
LINQ to SQL - mapping exception when using abstract base classes

Your repository should accept BankAccount - not IBankAccount because Linq-to-sql doesn't know what is IBankAccount and compiler doesn't allow you to store it without casting it first to BankAccount (that can obviously fail at runtime if IBankAccount instance is not a BankAccount).
Once you have BankAccount you simply call:
Context.BankAccounts.Add(account);
Context.SubmitChanges();

As far as I understand you need to model a banking system. This mean dealing with bank accounts. This is tough business that is no "Hello World!"-type information technology.
Basically with bank accounts you need to :
Read details (such as account name, value, etc
Debit account
Credit account
Terminate account
Create a new account
... and other operations
The debit and credit operations are the most "transactional" operations of them all since these mean that you'll be editing two accounts at a time and you want to succeed both editings or fail both at once.
This, again, is a risky business since it involves checking a lot of business rules beginning with having enough money on the account (that is not that simple since having an overdraft account means you can go below zero) all the way to ensuring there is a durable transaction that substracts money from one account and adds money to another one.
Also you must check that a person does not try to transfer negative amounts of money because that will be literally stealing money from other accounts. And the list does not stop here. Scott Hanselman worked in a bank for some time and he might be of some help regarding what needs to be checked.
All in all, my response seems to be a "not worthy" one and you might just as well downvote me but, again, the subject is too deep to be covered in a stackoverflow response.
Sorry.

Related

Migrate from CRUD to DDD

Now I want to try to start from the objects of my model according to the dictates DDD but I have some difficulty in understanding how to migrate my thought patterns because I can not turn the examples that I find lying around on my specific case .
My main concept are the activities , each activity has an indicative code , a description , a status that changes over time and a quarter each Result.
Users want to be able to see the history of all the states hired from the activities, with the dates on which the changes were made . In addition, they also want to be able to create new states, change the description of the existing ones and possibly prevent the use of some of these while maintaining the value for the previous activities .
Each quarter, users want to be able to insert an Result that contains Outcome and recommendations, a rating and the date of formulation of the outcome .
The ratings must be a list freely maintainable by users.
Thinking to my old way I would create classes like this:
public class Activity
{
public int ID;
public string Desc;
public IList<ActivityStatus> ActivityStatusList;
public IList<Result> ResultList;
}
public class ActivityStatus
{
public Activity Activity;
public Status Status;
public DateTime StartDate;
public DateTime EndDate;
}
public class Status
{
public int ID;
public string Desc;
public bool Valid;
}
public class Result
{
public Activity Activity;
public int Quarter;
public string Outcome;
public string Recommendations;
public Rating Rating;
}
public class Rating
{
public int ID;
public string Desc;
public bool Valid;
}
than i will implement a DataAccessLayer mapping this class to a new db (created from this class) with NHibernate and add repository to grant user CRUD operation to all of this object
According to DDD are there better ways?
I'd recommend to read the book or at least the Wikipedia article.
DDD is about focussing on domain logic and modelling this first - in an object-oriented way. Persistence is a technical concern, which should not be the starting point of your design and (usually) not determine, how you will design your domain classes.
If you're eager to code and believe you understand the domain well, I would suggest a BDD test-first approach. Use tools like SpecFlow to describe your business processes in plain english, then gradually fill in the steps and functionality as you go, using mocks, design patterns, inversion of control etc.
Background reading is a must if you're unfamiliar with DDD. Read the book that EagleBeak suggests, get clued up on SOLID principles and experiment yourself.
I can´t tell if there are better ways but what you said would be one way to solve this problem in a DDD fashion.
In my data access layer I typically use an abstract factory of respositories. This way I can plug an specific implementation for data access such as NHibernate.
public interface IRepositoryFactory {
T Repository<T>();
};
public class NHibernateRepositoryFactory {
T Repository<T>() {
..... // find class that implements T in Assemblies with reflection
return repository;
}
};
public static class Persistence {
IRepositoryFactory Factory { get; set; }
};
This way you can call your repository without referencing any specific implementation:
User user = Persistence.Factory.Get<IUserRepository>().FindByEmail("john#tt.com");
user.name = "James";
Persistence.Factory.Get<IUserRepository>().save(user);
Another advantage of using abstract factories for repositories as above is that you can test your code by pluging a fake implementation for the repository.
public class FakeRepositoryFactory {
T Repository<T>() {
..... // find class that implements T in Assemblies of fake repositories
return repository;
}
};
public class FakeUserRepository : public IUserRepository {
User FindByEmail(string email) {
// create mocked user for testing purposes ....
return userMock;
}
};
Your code will not and should not know where the user data is coming from with abstract factories for persistence. This way switch from one way to another can be done in a transparent way.

EF Code First - How to Model This?

I'm working on a web app (MVC) utilizing Entity Framework code first and I'm trying to figure out how to model this. I could certainly add 15 bool values to a class (bits in the database), but that seems like a pathetic way to go about it. I currently have a customer object that will contain an object for the policies shown in the image below.
I want my view to look just like what is above and there are currently no plans to add a 6th, but architecting the model to support that possibility would be important.
public class customer{
//some random properties like Id, Name, Owner, Etc.
//I could put 15 bools here for the policies in the image
//I could put a policy object here?
}
Here is a design that is simple, self describing, scalable, normalized and extensible. You can add additional policy types or patient types without recompiling the system. You didn't state which database engine you are using, so in order to make it work across most database platforms, I'd suggest you use TPC.
A patient is just a role that a person (aka party) plays in the system. You can have other roles such as "doctor", "employee", "policy holder" and so forth each with their own data. It is important to note that roles are temporal, meaning a single role can be voided, while the person performs other roles in the system.
If "Existing", "AgeIn", "NewPatient" can be determined by looking at properties of the Role or Party, the there is no need for a PatientType. I added it because it is unclear how the types of patiences are defined. You may very well just have a property on Patient to define that.
A party represents any legal entity. Parties have relationships which are often important for a business. So when "Sam" (a person) comes to the "Doctor" (a person playing a role), it is important to know that a "policy" of her dad Bob (a person) will be paying the bill. Hence the reason a Person is mapped in a different table.
PolicyType defines what type of policy a policy really is. In your case, you may have 18 different policy types, like ExistingOriginalMediCare, AgeInOriginalMediCare and so forth. This is where you can store data that influences the "rules" of your policy. For example, some types of policies are only available to people living in California. One system I worked on had thousands of policy types each with hundreds of properties that applications used to infer business rules. This allowed business to create new policy types and "rules" without recompiling the system and everything that depended on it.
However, one can simplify it by taking out the inheritance while maintaining the same capabilities. Here we assume that there will be no other "role" than "patient" and no other "party" than a "person".
That said, it really depends on whether the data will be reused by other applications and how temporal data and associations really are. Feel free to adapt. I often reference these books when designing systems:
Enterprise Patterns and MDA: Building Better Software with Archetype Patterns and UML
Enterprise Model Patterns: Describing the World (UML Version)
The Data Model Resource Book, Volume 3: Universal Patterns for Data Modeling
They have fundamentally changed the way I look at "data".
You could take a look at TPT (Table Per Type) for this, take a look here http://blogs.microsoft.co.il/blogs/gilf/archive/2010/01/22/table-per-type-inheritance-in-entity-framework.aspx
This would mean that you could have a table for each of these different concepts which extend a base table. The bonus of doing it this way is that later on you can add additional info to a specific type.
EG, customer would be your root table and then be extended with concepts such as OriginalMedicareCustomer
If you want to normalize it, I recommend going about it like so:
public class Customer {
// id, name, owner, etc
public virtual IList<CustomerPolicy> Policies { get; set; }
}
public class CustomerPolicy {
// id, name, etc
public bool ExistingPatient { get; set; }
public bool AgeInPatient { get; set; }
public bool NewPatient { get; set; }
}
Without knowing more about your application, I can't say, but I'm guessing that the three booleans for each policy are mutually exclusive? If so, I would instead do something like this:
public enum PatientType { Existing, AgeIn, NewPatient };
public class CustomerPolicy {
// id, name, etc
public PatientType PatientType { get; set; }
}
I'm not entirely sure about your data requirements, but I'd keep it simple and within a table or two, something like this...
public class Customer
{
public int CustomerID { get; set; }
// or implement it via enum like below for policy type
public bool Existing { get; set; }
public bool AgeIn { get; set; }
public bool New{ get; set; }
// no 'virtual' means it's 'required', with virtual could be 'null'
public Policy Policy { get; set; }
}
public enum PolicyBits
{
None = 0x00,
ExistingOriginalMediCare = 0x01,
// ...
AgeInOriginalMediCare = 0x100,
// ...
}
public class Policy
{
public int PolicyID { get; set; }
public int PolicyTypeValue { get; set; }
[NotMapped]
public PolicyBits PolicyType
{
get { return (PolicyBits)PolicyTypeValue; }
set { PolicyTypeValue = (int)value; }
}
}
...enum would help you scale down on the number of 'bits' - but it's not officially supported yet, will be from the next version and so far only in experimental, VS 2011 and .NET 4.5 (as I recall).
but you can temporarily work around it with something like below.
As for the model of the tables - I'm not sure how you want to 'switch' in between existing, new or age-in users - or could you have both or all three at the same time etc. Since all are bits I'm thinking one field should be enough - and maybe put it into a separate table for separation mostly - i.e. so you could redefine that, add new things or introduce new records etc.

Altering Domain Entities When Changing Persistence Layer

In my app, I've been using a DB that stored its IDs as strings. The DB also stored another property (Etag) for each document/row. Because of that, I've had my domain entities derive from this base class:
public class EntityBase : NotifyPropertyChangedBase
{
public string Id { get; set; }
public Guid ETag { get; set; }
}
Now I'm adding another data layer to my application, and I don't want to remove the old one. It would be nice to be able to switch and use a particular data layer based on a run-time decision. The issue is that I want to store Id as an int in the new DB. And ETag is an unnecessary concept in that new DB.
I'm struggling with how to manage this change. If I change EntityBase.Id to an int, then the old data layer won't compile. I'd like to use a certain EntityBase if using the old data layer, and a different EntityBase if I'm using the new data layer. That's just one thought. Maybe there's a better approach? Any suggestions on how I can make this work?
By the way, I believe that persistence layer issues shouldn't work there way up into domain layer objects (like Id being a string or int). However, it's too late, and this is the situation in which I find myself. I'm hoping someone has some good advice on how to proceed.
I was thinking about adding an Id2 to EntityBase:
public class EntityBase : NotifyPropertyChangedBase
{
public string Id { get; set; }
public int Id2 { get; set; } // New property for new DB only
public Guid ETag { get; set; }
}
Then, in my new DAL mapping, I would map the Id column in the table to Id2 instead of Id. But that's not going to work because my business logic references Id only. Still thinking... I may be stuck...
As a hack, I could leave EntityBase in its original form. Then, in the new DAL, when I perform the ORM, I could just convert the ID of the table to a string.
I suggest to add one more layer then.
For instance, to create a new class like this:
public abstract class CommonEntityBase<T> : NotifyPropertyChangedBase{
public T Id {get;set;}
}
And then, derive your old EntityBase from this class:
public class EntityBase : CommonEntityBase<string>{
//this property is present only in this old implementation
public Guid ETag { get; set; }
}
So now, you can create a new layer and use a base class for that as well:
public class FancyEntityBase : CommonEntityBase<int>{
//No ETag concept here - ad new properties, methods, etc.
}
However, there is a question if you really need to change your primary keys to be integers.
This may result in performance issues when the ORM is used.

Wrapping DbSet<TEntity> with a custom DbSet/IDbSet?

First off, I think this is somewhat ridiculous to do but the other members of my team insist upon it and I can't come up with a good argument against it other than "I think it's dumb"...
What we're trying to do is create a completely abstract data layer and then have various implementations of that data layer. Simple enough, right? Enter Entity Framework 4.1...
Our end goal here is that the programmers (I do my best to stay only on the data layer) never want to have to be exposed to the concrete classes. They only ever want to have to use interfaces in their code, aside from obviously needing to instantiate the factory.
I want to achieve something like the following:
First we have our "Common" library of all of the interfaces, we'll call it "Common.Data":
public interface IEntity
{
int ID { get; set; }
}
public interface IUser : IEntity
{
int AccountID { get; set; }
string Username { get; set; }
string EmailAddress { get; set; }
IAccount Account { get; set; }
}
public interface IAccount : IEntity
{
string FirstName { get; set; }
string LastName { get; set; }
DbSet<IUser> Users { get; set; } // OR IDbSet<IUser> OR [IDbSet implementation]?
}
public interface IEntityFactory
{
DbSet<IUser> Users { get; }
DbSet<IAccount> Accounts { get; }
}
From that we then have an implementation library, we'll call it "Something.Data.Imp":
internal class User : IUser
{
public int ID { get; set; }
public string Username { get; set; }
public string EmailAddress { get; set; }
public IAccount Account { get; set; }
public class Configuration : EntityTypeConfiguration<User>
{
public Configuration() : base()
{
...
}
}
}
internal class Account : IAccount
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DbSet<IUser> Users { get; set; } // OR IDbSet<IUser> OR [IDbSet implementation]?
public class Configuration : EntityTypeConfiguration<Account>
{
public Configuration() : base()
{
...
}
}
}
Factory:
public class ImplEntityFactory : IEntityFactory
{
private ImplEntityFactory(string connectionString)
{
this.dataContext = new MyEfDbContext(connectionString);
}
private MyEfDbContext dataContext;
public static ImplEntityFactory Instance(string connectionString)
{
if(ImplEntityFactory._instance == null)
ImplEntityFactory._instance = new ImplEntityFactory(connectionString);
return ImplEntityFactory._instance;
}
private static ImplEntityFactory _instance;
public DbSet<IUser> Users // OR IDbSet<IUser> OR [IDbSet implementation]?
{
get { return dataContext.Users; }
}
public DbSet<IAccount> Accounts // OR IDbSet<IUser> OR [IDbSet implementation]?
{
get { return dataContext.Accounts; }
}
}
Context:
public class MyEfDataContext : DbContext
{
public MyEfDataContext(string connectionString)
: base(connectionString)
{
Database.SetInitializer<MyEfDataContext>(null);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new User.Configuration());
modelBuilder.Configurations.Add(new Account.Configuration());
base.OnModelCreating(modelBuilder);
}
public DbSet<User> Users { get; set; }
public DbSet<Account> Accounts { get; set; }
}
Then the front-end programmers would be using it such as:
public class UsingIt
{
public static void Main(string[] args)
{
IEntityFactory factory = new ImplEntityFactory("SQLConnectionString");
IUser user = factory.Users.Find(5);
IAccount usersAccount = user.Account;
IAccount account = factory.Accounts.Find(3);
Console.Write(account.Users.Count());
}
}
So that's pretty much it... I'm hoping someone on here might be able to either point me in the right direction or help me out with a good argument that I can fire back at the development team. I've looked at some other articles on this site about EF not being able to work with interfaces and one reply saying that you can't implement IDbSet (which I find kind of curious, why would they provide it if you couldn't implement it?) but so far to no avail.
Thanks in advance for any help!
J
The first argument is that EF doesn't work with interfaces. DbSet must be defined with a real entity implementation.
The second argument is that your entities should not contain DbSet - that is context related class and your entities should be pure of such dependency unless you are going to implement Active record pattern. Even in such case you will definitely not have access to DbSet of different entity in another entity. Even if you wrap set you are still too close to EF and entity never have property accessing all entities of another entity type (not only those related to current instance).
Just to make it clear DbSet in EF has very special meaning - it is not a collection. It is entry point to database (for example each LINQ query on DbSet hits database) and it is in normal scenarios not exposed on entities.
The third argument is that you are using a single context per application - you have a single private instance per singleton factory. Unless you are doing some single run batch application it is definitely wrong.
The last argument is simply practical. You are paid for delivering features not for wasting time on abstraction which doesn't give you (and your customer) any business value. It is not about proving why you should not create this abstraction. It is about proving why you should do it. What value will you get from using it? If your colleagues are not able to come with arguments which have business value you can simply go to your product manager and let him use his power - he holds the budget.
Generally abstraction is part of well designed object oriented application - that is correct. BUT:
Every abstraction will make your application somehow more complex and it will increase cost and time of development
Not every abstraction will make your application better or more maintainable - too much abstraction has reverse effect
Abstracting EF is hard. Saying that you will abstract data access in the way that you can replace it with another implementation is task for data access gurus. First of all you must have very good experience with many data access technologies to be able to define such abstraction which will work with all of them (and in the end you can only tell that your abstraction works with technologies you thought about when you design that). Your abstraction will work only with EF DbContext API and with nothing else because it is not an abstraction. If you want to build universal abstraction you should start studying Repository pattern, Unit of Work pattern and Specification pattern - but that is a big deal of work to make them and to implement them universal. The first step needed is to hide everything related to data access behind that abstraction - including LINQ!
Abstracting data access to support multiple APIs make sense only if you need it now. If you only think that it can be useful in future than it is in business driven projects completely wrong decision and developer who came with that idea is not competent to make business targeting decisions.
When it make sense to do "a lot of" abstraction?
You have such requirement now - that moves burden of such decision to person responsible for budget / project scope / requirements etc.
You need abstraction now to simplify design or solve some a problem
You are doing open source or hobby project and you are not driven by business needs but by purity and quality of your project
You are working on platform (long living retail product which will live for a long time) or public framework - this generally returns to the first point because this type of products usually have such abstraction as requirement
If you are working only targeted application (mostly single purpose applications on demand or outsourced solutions) the abstraction should be used only if necessary. These applications are driven by costs - the target is delivering working solution for minimal costs and in the shortest time. This target must be achieved even if resulting application will not be very good internally - the only thing which matters is if application meets requirements. Any abstraction based on "what if ... happens" or "perhaps we will need ..." increases costs by virtual (non existing) requirements which will in 99% never happen and in most cases initial contract with customer didn't count which such additional costs.
Btw. this type of applications is targeted by MS APIs and designer strategy - MS will make a lot of designers and code generators which will create non optimal but cheap and quick solutions which can be created by people with smaller skill set and are very cheap. The last example is LightSwitch.

ASP.NET MVC: Where should this business logic go?

I'm working on my first real MVC application and I'm trying to follow general OOP best practices. I'm refactoring some simple business logic that I had in a controller into my domain model. I've been doing some reading lately and it seems pretty clear that I should put the logic somewhere in a domain model entity class in order to avoid the "anemic domain model" anti-pattern.
The application will allow people to purchase leases for parking spaces. Rates are determined by the length of the spot and whether or not the customer is a member of the business park.
So I have entity classes in my domain model that look like this (simplified):
public class Customer
{
int ID { get; set; }
string Name { get; set; }
bool IsMember { get; set; }
}
public class ParkingSpace
{
int ID { get; set; }
int Length { get; set; }
}
public class ParkingSpaceLease
{
int ID { get; set; }
DateTime OpenDate { get; set; }
DateTime CloseDate { get; set; }
Customer Customer { get; set; }
ParkingSpace ParkingSpace { get; set; }
}
Edit: Just to clarify the LeaseQuote is not an entity class as it is just used to display the cost breakdown to perspective customers and is not persisted anywhere.
public class LeaseQuote
{
int SubTotal { get; set; }
int Discount { get; set; }
int Total { get; set; }
}
Now as a feature of the application I need to be able to generate quotes for different customer and parking space combinations. The quotes will normally be accessed outside the context of actually creating a lease such as when a customer calls up to inquire about a price.
So what is the best way to go about this? Does it make sense to instantiate a new ParkingSpaceLease object inside the controller just to call a GetQuote method on it?
var lease = new ParkingSpaceLease();
var quote = lease.GetQuote(length: 168, isMember: true);
return Json(quote);
Or should the LeaseQuote class have the method?
var leaseQuote = new LeaseQuote();
var quote = leaseQuote.GetQuote(length: 168, isMember: true);
return Json(quote);
It feels strange putting the logic in the actual ParkingSpaceLease class. I guess it feels kind of "heavy" to create a new lease object when I know that I'm not going to actually do anything with it other than access the GetQuote method which seems kind of like a separate service.
So where should the GetQuote method go and why should it go there?
It almost sounds like your LeaseQuote isn't an entity and more of a business level class. I mean, you're not storing it in the database anywhere, are you? And it's not a part of another data object.
When I see this
Now as a feature of the application I need to be able to generate quotes for different customer and parking space combinations. The quotes will normally be accessed outside the context of actually creating a lease such as when a customer calls up to inquire about a price.
I think of a method signature like this
public LeaseQuote GetQuote(Customer customer, ParkingSpace parkingSpace, int length)
But with that in mind, I'd probably also want to store information about the cost of the parking space within the ParkingSpace entity and (if applicable) the customer's discount in the Customer entity.
Where would this stuff go? In a model class (business model, not LINQ or Entity model) that accesses your entities and serves as a provider for your controller.
Now I know that's not using your models exactly as written. And it could just be personal bias. But when I think about data models and data entities, they should not have any addon methods outside of what's coming back from the database. They should just represent the data unaltered as it appears in the database. If you're acting on the data, that belongs in a tier above the data entities.
Update:
What I am curious about from your example is why one would want to pass the full Entity objects (Customer and Parking Space) versus just the properties needed to perform the calculation?
It depends on your standard of code. Exposing the entity itself could be dangerous if the consuming code manipulates the entity. I prefer passing the entity mainly because that's what I'm used to. But I'm also careful not to manipulate the entity on the way in. That, and I think the method signature reflects what the GetQuote method is focused on; it's related to a customer and a parking space.
I could also make the case that if more fields go into the Entity later that can effect the GetQuote method, then the method signature doesn't have to change. In this case, only the implementation for GetQuote has to change.
Short answer: Preference.
Just make GetQuote a static method in ParkingSpaceLease.
I think you may have your object model slightly askew, which would lead to your concern about the lease being the wrong place from which to get a quote. It seems to me that a lease would be wholly composed by the parking space which is being leased, and would be related only to the customer purchasing the lease. IOW:
public class ParkingSpace
{
int ID { get; set; }
int Length { get; set; }
IEnumerable<ParkingSpaceLease> Leases { get; set; }
LeaseQuote GetQuote(Customer customer/*, other relevant parameters */) { ... }
}
public class ParkingSpaceLease
{
int ID { get; set; }
DateTime OpenDate { get; set; }
DateTime CloseDate { get; set; }
Customer Customer { get; set; }
}
public class LeaseQuote
{
//Properties
ParkingSpaceLease GetLease();
}
EDIT I missed the part about the LeaseQuote being a separate class.

Categories

Resources