Group methods in Abstract Class - c#

I'm working on a database factory pattern for an application which should support Sql Server and Oracle. I've an abstract classes with all the Sql Queries for the application. I've implemented the abstract class in two classes: SqlServerClass and OracleClass. Based on the connection string defined in the configuration file, the application creates an instance of the corresponding class and get the Sql queries for the database.
public abstract class ProviderFactory
{
public abstract string GetCustomersSql();
public abstract string GetCustomersByIdSql();
public abstract string GetUsersSql();
public abstract string GetUsersByIdSql();
}
public class OracleClass : ProviderFactory
{
public override string GetCustomersSql()
{
// return sql query for Oracle
}
// other methods
}
public class SqlServerClass : ProviderFactory
{
public override string GetCustomersSql()
{
// return sql query for Sql Server
}
// other methods
}
Now my question is, Is there a way to group these sql queries in the abstract class so that one can easily identify the sql queries used for particular functionality. For example, Can I group all Customers related queries and Users related queries so that when I refer them, it would be like....
ProviderFactory instance;
// create an instance
instance.Customers.GetCustomersSql();
Is what I'm doing here a valid approach? Please suggest. Thank you.

I would strongly recommend using an ORM such as NHibernate. It supports both SQL Server and Oracle and abstracts away the differences between the two.
By that I mean you only have to write the query once in a format NHibernate understands and it will translate that to versions that SQL Server and Oracle understand.
If you want to continue down your current path what you can do is create what I'd call a query directory:
public interface IQueryDirectory
{
ICustomerQueries Customer { get; }
IUserQueries User { get; }
}
public interface ICustomerQueries
{
string Customers { get; }
string CustomersById { get; }
}
public interface IUserQueries
{
string Users { get; }
string UsersById { get; }
}
Example implementation:
public abstract class QueryDirectory : IQueryDirectory
{
private ICustomerQueries customer;
private IUserQueries user;
public ICustomerQueries Customer
{
get { return customer; }
}
public IUserQueries User
{
get { return user; }
}
protected QueryDirectory(ICustomerQueries customer, IUserQueries user)
{
this.customer = customer;
this.user = user;
}
}
public class SqlServerQueryDirectory : QueryDirectory
{
public SqlServerQueryDirectory(SqlServerCustomerQueries customer,
SqlServerUserQueries user) : base(customer, user) {}
}
public class SqlServerCustomerQueries : ICustomerQueries
{
public string Customers
{
get "some sql";
}
public string CustomersById
{
get "some sql";
}
}
Then you can implement the directories seperately for each database. But honestly, I really, really, really recommend using an ORM instead.

Related

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

Abstract away the DAL from Entity Framework implementation

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".

Using Base Entity Context for code first Entity Framework

TLDR: Why is Entity Framework appending extra path to the end of my datasource? What do I need to do in order to use this framework? Is there another way to handle this?
I am writing a basic SQL Server CE winforms program to store some data. I originally had 1 context to be used to interact with 1 class. Now, I wish to add another class, and so I refactored out a base context that the original context could be derived from. I have the code running, although I can't create any database with it.
I take a path in from the user to the database and set the |DataDirectory|, which I use for the data source.
<add name="MonsterContext"
connectionString="Data Source=|DataDirectory|; Persist Security Info=False"
providerName="System.Data.SqlServerCe.4.0" />
I intend for the data source to look like
C:Path\To\DatabaseFile.sdf
but it comes out as
C:\Path\To\DatabaseFile.sdf\Namespace.BaseContext`1[Namespace.ModelClass].sdf ]"}
I think this path demonstrates that it is building its own source based on EF defaults.
My base Context is:
public class EntityContext<T> : DbContext where T : class
{
public string TableName { get; set; }
public EntityContext()
: base("name=MonsterContext")
{
}
public EntityContext(string tableName)
{
this.TableName = tableName;
}
public DbSet<T> Entities { get; set; }
}
And My Derived Context is:
public class MonsterReader : Reader<Monster>
{
private List<Monster> monsters;
public List<Monster> Monsters
{
get
{
if (monsters == null)
{
monsters = ReadAll();
}
return monsters;
}
private set { monsters = value; }
}
public MonsterReader(string file)
: base(file)
{ }
public MonsterReader(Stream reader)
: base(reader)
{ }
public void CreateMonsterDatabase(IEnumerable<Monster> monsters)
{
CreateDatabase(monsters, TableName);
}
private string TableName { get; set; }
}
In this problem, it was a simple omission from the base context.
In the Base Entity Context, the first constructor is:
public EntityContext()
: base("name=MonsterContext")
{
}
However, the constructor that takes a table name is
public EntityContext(string tableName)
{
this.TableName = tableName;
}
which is missing the : base("name=MonsterContext")
This call is necessary if you want to call a specific connection string from the app.config.
In this case, the connection string you want to call is "Monster Context". Without specifying which context, Entity Framework defaults using SQL Server CE to
|DataDirectory|\Namespace.NameofContext.sdf

Repository pattern on multiple data provider/ORM?

Let just say I have the following data models:
public class Account
{
public string Username { get; set; }
public string Password { get; set; }
}
public class Configuration
{
public string Key { get; set; }
public string Value { get; set; }
}
For now, each of them has their own repository for data access, and uses entity framework as its unit of work/DbContext. I'm planning to pull out the Configuration part out of the entity frame and use Redis or Memcached as its data access. I might even to switch the EF to NHibernate or no ORM at all, and I might switch the database to MongoDB or CouchDB.
What is the good way to do this? To be ignorant of all those lower layer stuff in my business logic? What kind of pattern to use? Is it possible or is it just bad things to design for changes like this?
Thanks :)
As stated in the previous post, you should go the "way of the Interface".
I personally do not implement directly the repository for each orm but I use a little variation.
Using your example...
public interface IAccountRepository
{
Account Get(int id);
void Delete(int id);
...other method...
}
then you create your repository
public class AccountRepository : IAccountRepository
{
private readonly IUnitofWork unitofWork;
public AccountRepository(IUnitofWork unitofWork)
{
this.unitofWork = unitofWork;
}
//Implement interface method
public Account Get(int id)
{
//some logic or just the call to the unit of work
return unitofWork.Get(id);
}
}
I am happy with this solution because I end up with only one repository that 90% of the time use linq to query so I don't have to write the sql for each unit of work and every time I have to write a "GetAllProducts" with paging I do not have to write the same code (and tests) for every unit of work, but only for my repository. This is a simple example obviously so I hope you get the idea.
You can make a RepositoryBase that implement a method Find() or Query() which use linq.
Then with your Castle Windsor or ninject or whatever you can inject the unit of work you prefer. Hope it helps.
Update:
a sample of my UnitofWorkBase that implement nhibernate is something similar:
public class NHUnitofWork<T> : IUnitofWork<T> where T : EntityBase
{
protected INHSessionBuilder SessionBuilder { get; private set; }
public NHPersistorBase(INHSessionBuilder sessionBuilder)
{
SessionBuilder = sessionBuilder;
}
public T Get(int id)
{
T result = null;
ISession session = SessionBuilder.GetSession();
using (ITransaction transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
try
{
result = (T)session.Get(typeof(T), id);
transaction.Commit();
}
finally
{
if (transaction.IsActive)
transaction.Rollback();
}
}
return result;
}
public IQueryable<T> Find()
{
return SessionBuilder.GetSession().Query<T>();
}
}
Use an interface.
public class IAccountRespository
{
public Account LoadAccountByUsername(String Username);
public void DeleteAccont(Account a);
public void SaveAccont(Account a);
.
.
.
...more methods
}
then you implement this interface on every data access object (ef,mongdb, etc. etc).
In your business logic code you use just the interface and not the acual object.
i use the factory pattern to create the data access objects, but you can use every IoC pattern.

Too Much Abstraction/Interfaces

I am in the process of designing my data access code, the data is going to be stored in RavenDB, and I am trying to see if my current design has too much abstraction with the number of interfaces I am going to have.
I am going to have DTOs that will just hold the data and then I am going to have Entity (or Model, Business, or whatever you call them) objects that will have extra functionality. I am also going to have an interface per entity defining what data it needs to have. So for example:
interface IUser
{
string Id { get; }
string Username { get; }
string Password { get; }
bool ResetPassword { get; }
}
class UserDTO : IUser
{
public string Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public UserDTO()
{
Id = null;
Username = null;
Password = null;
ResetPassword = false;
}
}
class User : IUser
{
public string Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public User()
{
Id = null;
Username = null;
Password = null;
ResetPassword = false;
}
public User(IUser user)
{
Id = user.Id;
Username = user.Username;
Password = user.Password;
ResetPassword = user.ResetPassword;
}
public ResetPassword()
{
Id = null;
Username = null;
Password = null;
}
}
The reason I want to have an interface for each entity is because I want to make sure the both EntityDTO and Entity have the required shared data.
Now for retrieving and saving the data, I am going to use the repository pattern. I am going to have one generic interface called IDataRepository and then each entity is going to have is own repository interface. For example:
interface IDataRepository<T>
{
bool Save(T entity);
bool Delete(T entity);
}
interface IUserRepository : IDataRepository<IUser>
{
IUser Load(string key);
IUser LoadByLogin(string username, string password);
}
class UserRepository : IUserRepository
{
bool Save(T entity)
{
//save code
}
bool Delete(T entity)
{
//delete code
}
IUser Load(string key)
{
//load code
}
IUser LoadByLogin(string username, string password)
{
//load code
}
}
The reason I want to have a repository interface for each entity is so that I can if I need to use different data storage options for different entities.
Do this seem like too much abstraction?
I think this model has its goods and bads. If your DTO is going to match the Entity, why have the DTO? In some systems this is something that needs to happen and in others it is a waste of time. Entities usually have baggage and dont serialize well depending on the ORM. If you use that interface the mapping between the DTO and Entity can be done with AutoMapper and should work well every time. Do you need to have the Entity class live in an separate DLL from the DTO? If so I think your model works.
Yes, this is too much abstraction. Specifically, I do not see a need for the UserDTO class of objects.
IUser itself should define the complete interface necessary for the data repository to do its job. If the repository is handed an object that implements IUser, like User for example, then it should be able to store the data just fine. And, since the interfaces are defined at the lowest level, omitting the UserDTO object will not create any dependency problems.
What you have, in essence, seems fine to me.
However, unless you have further distinction between the DTO and Entity classes and a clear need to separate the two, I would simply have User extends UserDTO and remove the interface all together. That way, you remove the code redundancy that you currently have.

Categories

Resources