I am trying to design my application architecture using ado.net with sql server. I am consider to use threee layers as follows:
Presentation Layer -> Business Layer (BAL) -> Data access Layer (DAL)
Entities for sample objects like Employee, Department etc..
I am trying to use interfaces as a contracts for some of my classes. My current issue is that i see some of the methods are common between BAL and DAL objects like: Add, Remove, GetAll therefore i decided to create interfaces to implement such things however when using from BAL classes i need to have it like void Add(Employee) but in DAL void Add(string name); therefore i splitted almost same interfaces on DAL and BAL (i do not like it because it seems to be somehow duplicated). Next issue is when want to use my code at the StickTogether class i am not able to call for instance _employee.Department = _department; I know it's because Department property should be in RepositoryBal interface but then simple entity Department would need to implement such interface which i dont want to do because as far as i read entities are just simple repeesentation of specific object. Could you tell me - best show on example how you would create such architecture or modify my to have something better than what i have right now. Below find my full code i am working on. How this could be fixed?
Please note i also start to prepare this code for dependency which will be helpfull for moc tests.
Appreciate your answers with proposed fixed solution based on my code.
public class StickTogether
{
private readonly IRepositoryBal<Employee> _employee;
private readonly IRepositoryBal<Department> _department;
public StickTogether(IRepositoryBal<Employee> employee, IRepositoryBal<Department> department)
{
_employee = employee;
_department = department;
}
public void Create()
{
_employee.Add(new Employee());
_department.Add(new Department());
_employee.Department = _department; //not accessible which has a sense
}
}
public interface IEntity
{
int Id { get; set; }
}
public class Employee : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public Department Department { get; set; }
}
public class Department : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
public interface IRepositoryDal<T> where T : IEntity
{
void Add(string name);
void Delete(int id);
IEnumerable GetAll();
}
public interface IRepositoryBal<T> where T : IEntity
{
void Add(T entity);
void Delete(T entity);
IEnumerable<T> GetAll();
}
internal class DepartmentBal : IRepositoryBal<Department>
{
private readonly IRepositoryDal<Department> _departmentDal;
public DepartmentBal(IRepositoryDal<Department> department)
{
_departmentDal = department;
}
public void Add(Department entity)
{
_departmentDal.Add(entity.Name);
}
public void Delete(Department entity)
{
_departmentDal.Delete(entity.Id);
}
public IEnumerable<Department> GetAll()
{
return (IEnumerable<Department>)_departmentDal.GetAll();
}
}
public class DepartmentDal : IRepositoryDal<Department>
{
public void Add(string name)
{
//call sql server stored procedure to add department;
}
public void Delete(int id)
{
//call sql server stored procedure to delete department by id;
}
public IEnumerable GetAll()
{
//call sql server stored procedure to return all employees;
return null;
}
}
internal class EmployeeBal : IRepositoryBal<Employee>
{
private readonly IRepositoryDal<Employee> _employeeDal;
public EmployeeBal(IRepositoryDal<Employee> employee)
{
_employeeDal = employee;
}
public void Add(Employee entity)
{
_employeeDal.Add(entity.Name);
}
public void Delete(Employee entity)
{
_employeeDal.Delete(entity.Id);
}
public IEnumerable<Employee> GetAll()
{
return (IEnumerable<Employee>) _employeeDal.GetAll();
}
}
public class EmployeeDal : IRepositoryDal<Employee>
{
public void Add(string name)
{
//call sql server stored procedure to add employee;
}
public void Delete(int id)
{
//call sql server stored procedure to delete employee by id;
}
public IEnumerable GetAll()
{
//call sql server stored procedure to return all employee;
return null;
}
}
The 3 layer (anti pattern?) is a red herring here, you're essentially talking a dependency injection. pattern. These become difficult to manage manually. I'd suggest you implement a DI framework like Simple Injector or Unity.
I am trying to use interfaces as a contracts for some of my classes.
Why some of your classes? If your going to implement dependency injection then implement it on all classes.
My current issue is that i see some of the methods are common between
BAL and DAL objects like: Add, Remove, GetAll therefore i decided to
create interfaces to implement such thing
Here's your first mistake. You've decomposed based on functionality, not responsibility. Just because something has a similar method signature does not mean they should be related. A Customer business object has a very different responsibility to a Customer data object. Remember favour composition over inheritance.
however when using from BAL classes i need to have it like void
Add(Employee) but in DAL void Add(string name);
This just highlights the above, you've made the decision that because the methods are called "Add" their the same, their obviously not.
I would say you should implement an interface for each object, dont' try and relate unrelated object, then configure this using a DI framework, then inject them. Try not to blur your lines and keep your seperations clear. Remember you want high cohesion and low coupling.
To give some examples I'd forget about your IRepositoryBal and the generics altogether and just simplify the whole thing:
//your going to struggle to do DI with internal classes, make them public
public class EmployeeBal : IEmployeeBal
{
//
}
public interface IEmployeeBal
{
void Add(Employee entity);
void Delete(Employee entity);
IEnumerable<Employee> GetAll();
Department Department {get; set;}
}
public class StickTogether
{
private readonly IEmployeeBal _employee;
private readonly IDepartmentBal _department;
public StickTogether(IEmployeeBal employee, IDepartmentBal department)
{
_employee = employee;
_department = department;
}
public void Create()
{
_employee.Add(new Employee());
_department.Add(new Department());
_employee.Department = _department; //not accessible which has a sense
}
}
You then configure these in your DI framework, for example in simple Injector you would do:
Container _defaultContainer = new Container();
_defaultContainer.Register<IEmployeeBal, EmployeeBal>();
_defaultContainer.Register<IDepartmentBal, DepartmentBal>();
_defaultContainer.Register<IDepartmentDal, DepartmentDal>();
//..etc.
you then get your parent instance (only!) thus:
IEmployeeBal entryPoint = _defaultContainer.GetInstance<IEmployeeBal>();
the DI framework does the rest and all your dependencies are decoupled.
Related
I'm using Entity Framework with DDD.
I have the following entities: Person, Customer, Employee
Person is abstract.
Customer and Employee inherit person.
Person has references to the Person Address (List).
Should I have a repository for each type or only for each concrete type? (Just Customer and Employee)
Could I have a repository Person then Customer and Employee repositories depend on it internally to avoid redundant code? (Using DI by constructor injection)
This isn't meant to give a complete application structure, but a good basis for designing what you may need when working with different Repositories and Inheritance etc.
// Model stuff...
public interface IBaseEntity
{
[Key]
int Id { get; set; }
}
public abstract class BaseEntity : IBaseEntity
{
[Key]
public virtual int Id { get; set; }
// Add some extra fields for all Models that use BaseEntity
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Display(Name = "Last Modified")]
public virtual DateTime LastModified { get; set; }
[ConcurrencyCheck]
[Timestamp]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public virtual byte[] Timestamp { get; set; }
}
public class Person : BaseEntity
{
// Person Model here...
}
public class Employee : Person
{
// Extra Employee Model items here
}
public class Customer : Person
{
// Extra Customer Model items here
}
// End Model stuff
// Repository stuff...
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T GetById(int? id);
T Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(int id);
void Commit(); // To save changes rather than performing a save after each Add/Update/Delete etc.
}
public class EFRepository<T> : IRepository<T> where T : class, IBaseEntity
{
public virtual IQueryable<T> GetAll()
{
return DbSet.AsQueryable<T>();
}
public virtual T GetById(int? id)
{
var item = DbSet.Find(id);
return item;
}
public virtual T Add(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Detached)
{
dbEntityEntry.State = EntityState.Added;
}
else
{
DbSet.Add(entity);
}
// SaveChanges() - removed from each DbSet, so can call on all changes in one transaction.
// Using Unit Of Work Pattern. Can still use it here though if wished.
return entity;
}
// And so on for each storage method.
}
public interface IEmployeeRepository: IRepository<Employee>
public interface ICustomerRepository: IRepository<Customer>
public class EmployeeRepository : EFRepository<Employee>, IEmployeeRepository
public class CustomerRepository : EFRepository<Customer>, ICustomerRepository
// End Repository stuff
Basically you can add new Models and their Repositories by declaring the interfaces and classes with virtually nothing inside them. Everything inherits from the base crud functionality etc.
You only need to add new methods for getting records from the database in special cases for the Model being added - FindEmployeeByHairColor(color) for example, all other EF Gets, Finds etc. are the same regardless of the type.
This can get very deep, using Services to provide access to the core methods in the Repositories, add the Unit Of Work pattern to combine several DbSets into one transaction, and so on.
But using this type of layout allows me to inject into each layer the particular Repository/Service I wish to use, and keeps all logic in a single class that is re-used throughout everything that uses similar logic.
Hope this helps.
I would just have repositories for Customer and Employee.
If there is shared logic between these encapsulate it in an abstract base class and have the repositories inherit from it.
So you would end up with this sort of structure:
public interface ICustomerRepo { }
public interface IEmployeeRepo { }
public abstract class PersonRepoBase<T> { }
public class CustomerRepo : PersonRepoBase<Customer>, ICustomerRepo { }
public class EmployeeRepo : PersonRepoBase<Employee>, IEmployeeRepo { }
I am learning about MVP, test driven approach and factory pattern. I want to write few simple classes for maintaining a person's data and repository. The person's data will be stored in sql and for testing in an xml. I read about StructureMap but do not want to use it instead want to use a simple factory implementation that can eventually also help me hooking in unit test cases. Here are my classes:
class Person
{
int id;
string name;
}
interface IPersonRepository
{
Person GetPerson(int id)
{
}
}
class PersonRepositorySql : IPersonRepository
{
Person GetPerson(int id)
{
//Fetch from sql
}
}
class PersonRepositoryXML : IPersonRepository
{
Person GetPerson(int id)
{
//Fetch from XML
}
}
static class PersonRepositoryFactory
{
static PersonRepositorySql Create()
{
return new PersonRepositorySql();
}
static PersonRepositoryXML CreateTest()
{
return new PersonRepositoryXML();
}
}
class Presenter
{
Presenter(View _view)
{
}
void DoSomething()
{
IPersonRepository fact = PersonRepositoryFactory.Create();
//fact.GetPerson(2);
}
}
class PresenterTest
{
void Test1()
{
IPersonRepository fact1 = PersonRepositoryFactory.CreateTest();
//fact1.GetPerson(2);
}
}
Please tell me if the approach I have taken is the right one and any other recommendations. Also since I have not passed objects in constructor does this no stand as an example of dependency injection?
First of all don't depend on classes if you want to have your code testable, depend on interface that is implemented by a class.
Classes that depend on your factories should expect it injected by their users. Thanks to this you can swap your repository in test project easily and without changes to tested code.
Therefore any factory you have should be changed to something like this:
class PersonRepositoryXML: IPersonRepository
{
public IPerson GetPerson(int id)
{
//Fetch from XML
}
}
public interface IPersonRepository
{
IPerson GetPerson(int id);
}
// a dependent class
class SomeDependentClass {
public SomeDependentClass(IPersonRepository repository) {
this.repository = repository;
}
public void Foo() {
var person = repository.GetPerson(10);
// do smth to the person :)
}
}
I would recommend reading this book for further details about Dependency Injection design pattern.
Context / Question
I've worked on numerous .NET projects that have been required to persist data and have usually ended up using a Repository pattern. Does anyone know of a good strategy for removing as much boilerplate code without sacrificing code base scalability?
Inheritance Strategy
Because so much of the Repository code is boiler plate and needs to be repeated I normally create a base class to cover the basics like exception handling, logging and transaction support as well as a few basic CRUD methods:
public abstract class BaseRepository<T> where T : IEntity
{
protected void ExecuteQuery(Action query)
{
//Do Transaction Support / Error Handling / Logging
query();
}
//CRUD Methods:
public virtual T GetByID(int id){}
public virtual IEnumerable<T> GetAll(int id){}
public virtual void Add (T Entity){}
public virtual void Update(T Entity){}
public virtual void Delete(T Entity){}
}
So this works well when I have a simple domain, I can quickly create a DRY repository class for each entity. However, this starts to break down when the domain gets more complex. Lets say a new entity is introduced that does not allow updates. I can break up base classes and move the Update method into a different class:
public abstract class BaseRepositorySimple<T> where T : IEntity
{
protected void ExecuteQuery(Action query);
public virtual T GetByID(int id){}
public virtual IEnumerable<T> GetAll(int id){}
public virtual void Add (T entity){}
public void Delete(T entity){}
}
public abstract class BaseRepositoryWithUpdate<T> :
BaseRepositorySimple<T> where T : IEntity
{
public virtual void Update(T entity){}
}
This solution does not scale well. Let's say I have several Entities that have a common method:
public virtual void Archive(T entity){}
but some Entities that can be Archived can also be Updated while others can't. So my Inheritance solution breaks down, I'd have to create two new base classes to deal with this scenario.
Compoisition Strategy
I've explored the Compositon pattern, but this seems to leave a lot of boiler plate code:
public class MyEntityRepository : IGetByID<MyEntity>, IArchive<MyEntity>
{
private Archiver<MyEntity> _archiveWrapper;
private GetByIDRetriever<MyEntity> _getByIDWrapper;
public MyEntityRepository()
{
//initialize wrappers (or pull them in
//using Constructor Injection and DI)
}
public MyEntity GetByID(int id)
{
return _getByIDWrapper(id).GetByID(id);
}
public void Archive(MyEntity entity)
{
_archiveWrapper.Archive(entity)'
}
}
The MyEntityRepository is now loaded with boilerplate code. Is there a tool / pattern that I can use to automatically generate this?
If I could turn the MyEntityRepository into something like this, I think that would by far be ideal:
[Implement(Interface=typeof(IGetByID<MyEntity>),
Using = GetByIDRetriever<MyEntity>)]
[Implement(Interface=typeof(IArchive<MyEntity>),
Using = Archiver<MyEntity>)
public class MyEntityRepository
{
public MyEntityRepository()
{
//initialize wrappers (or pull them in
//using Constructor Injection and DI)
}
}
Aspect Oriented Programming
I looked into using an AOP framework for this, specifically PostSharp and their Composition Aspect, which looks like it should do the trick, but in order to use a Repository I'll have to call Post.Cast<>(), which adds a very odd smell to the code. Anyone know if there's a better way to use AOP to help get rid of the compositor boilerplate code?
Custom Code Generator
If all else fails, I suppose I could work at creating a Custom Code Generator Visual Studio plug in that could generate the boiler plate code into a partial code file. Is there already a tool out there that would do this?
[Implement(Interface=typeof(IGetByID<MyEntity>),
Using = GetByIDRetriever<MyEntity>)]
[Implement(Interface=typeof(IArchive<MyEntity>),
Using = Archiver<MyEntity>)
public partial class MyEntityRepository
{
public MyEntityRepository()
{
//initialize wrappers (or pull them in
//using Constructor Injection and DI)
}
}
//Generated Class file
public partial class MyEntityRepository : IGetByID<MyEntity>, IArchive<MyEntity>
{
private Archiver<MyEntity> _archiveWrapper;
private GetByIDRetriever<MyEntity> _getByIDWrapper;
public MyEntity GetByID(int id)
{
return _getByIDWrapper(id).GetByID(id);
}
public void Archive(MyEntity entity)
{
_archiveWrapper.Archive(entity)'
}
}
Extension Methods
Forgot to add this when I initially wrote the question (sorry). I also tried experimenting with extension methods:
public static class GetByIDExtenions
{
public T GetByID<T>(this IGetByID<T> repository, int id){ }
}
However, this has two problems, a) I'd have to remember the namespace of the extension methods class and add it everywhere and b) the extension methods can't satisfy interface dependencies:
public interface IMyEntityRepository : IGetByID<MyEntity>{}
public class MyEntityRepository : IMyEntityRepository{}
Update: Would T4 Templates be a possible solution?
I have a single generic repository interface, which is implemented only once for a particular data storage. Here it is:
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T Get(object id);
void Save(T item);
void Delete(T item);
}
I have implementations of it for EntityFramework, NHibernate, RavenDB storages. Also I have an in-memory implementation for unit testing.
For example, here is a part of the in-memory collection-based repository:
public class InMemoryRepository<T> : IRepository<T> where T : class
{
protected readonly List<T> _list = new List<T>();
public virtual IQueryable<T> GetAll()
{
return _list.AsReadOnly().AsQueryable();
}
public virtual T Get(object id)
{
return _list.FirstOrDefault(x => GetId(x).Equals(id));
}
public virtual void Save(T item)
{
if (_list.Any(x => EqualsById(x, item)))
{
Delete(item);
}
_list.Add(item);
}
public virtual void Delete(T item)
{
var itemInRepo = _list.FirstOrDefault(x => EqualsById(x, item));
if (itemInRepo != null)
{
_list.Remove(itemInRepo);
}
}
}
Generic repository interface frees me from creating lot's of similar classes. You have only one generic repository implementation, but also freedom in querying.
IQueryable<T> result from GetAll() method allows me to make any queries I want with the data, and separate them from the storage-specific code. All popular .NET ORMs have their own LINQ providers, and they all should have that magic GetAll() method - so no problems here.
I specify repository implementation in the composition root using IoC container:
ioc.Bind(typeof (IRepository<>)).To(typeof (RavenDbRepository<>));
In the tests I'm using it's in-memory replacement:
ioc.Bind(typeof (IRepository<>)).To(typeof (InMemoryRepository<>));
If I want to add more business-specific queries for the repository, I will add an extension method (similar to your extension method in the answer):
public static class ShopQueries
{
public IQueryable<Product> SelectVegetables(this IQueryable<Product> query)
{
return query.Where(x => x.Type == "Vegetable");
}
public IQueryable<Product> FreshOnly(this IQueryable<Product> query)
{
return query.Where(x => x.PackTime >= DateTime.Now.AddDays(-1));
}
}
So you can use and mix those methods in the business logic layer queries, saving testability and easiness of repository implementations, like:
var freshVegetables = repo.GetAll().SelectVegetables().FreshOnly();
If you don't want to use a different namespace for those extension methods (like me) - ok, put them in the same namespace where repository implementation resides (like MyProject.Data), or, even better, to some existing business specific namespace (like MyProject.Products or MyProject.Data.Products). No need to remember additional namespaces now.
If you have some specific repository logic for some kind of entities, create a derived repository class overriding the method you want. For example, if products can only be found by ProductNumber instead of Id and don't support deleting, you can create this class:
public class ProductRepository : RavenDbRepository<Product>
{
public override Product Get(object id)
{
return GetAll().FirstOrDefault(x => x.ProductNumber == id);
}
public override Delete(Product item)
{
throw new NotSupportedException("Products can't be deleted from db");
}
}
And make IoC return this specific repository implementation for products:
ioc.Bind(typeof (IRepository<>)).To(typeof (RavenDbRepository<>));
ioc.Bind<IRepository<Product>>().To<ProductRepository>();
That's how I leave in piece with my repositories ;)
Checkout T4 Files for code generation. T4 is built into Visual Studio. See a tutorial here.
I have created T4 files for code generating POCO entities by inspecting a LINQ DBML and for their repositories, I think it would serve you well here. If you generate partial classes with your T4 file, you could just write code for the special cases.
To me, it seems that you divide the base classes and then want the functionality from both of them in one inheritor class. In such a case, composition is the choice. Multiple class inheritance would also be nice if C# supported it. However, because I feel the inheritance is nicer and reusability is still fine, my first option choice would go with it.
Option 1
I would rather have one more base class instead of the composition of the two. Reusability can be solved with static methods as well rather than the inheritance:
Reusable part is not visible outside. No need to remember the namespace.
static class Commons
{
internal static void Update(/*receive all necessary params*/)
{
/*execute and return result*/
}
internal static void Archive(/*receive all necessary params*/)
{
/*execute and return result*/
}
}
class Basic
{
public void SelectAll() { Console.WriteLine("SelectAll"); }
}
class ChildWithUpdate : Basic
{
public void Update() { Commons.Update(); }
}
class ChildWithArchive : Basic
{
public void Archive() { Commons.Archive(); }
}
class ChildWithUpdateAndArchive: Basic
{
public void Update() { Commons.Update(); }
public void Archive() { Commons.Archive(); }
}
Of course there's some minor repeated code, but that's just calling the ready-made functions from the common library.
Option 2
My implementation of the composition (or imitation of the multiple inheritance):
public class Composite<TFirst, TSecond>
{
private TFirst _first;
private TSecond _second;
public Composite(TFirst first, TSecond second)
{
_first = first;
_second = second;
}
public static implicit operator TFirst(Composite<TFirst, TSecond> #this)
{
return #this._first;
}
public static implicit operator TSecond(Composite<TFirst, TSecond> #this)
{
return #this._second;
}
public bool Implements<T>()
{
var tType = typeof(T);
return tType == typeof(TFirst) || tType == typeof(TSecond);
}
}
Inheritance and composition (below):
class Basic
{
public void SelectAll() { Console.WriteLine("SelectAll"); }
}
class ChildWithUpdate : Basic
{
public void Update() { Console.WriteLine("Update"); }
}
class ChildWithArchive : Basic
{
public void Archive() { Console.WriteLine("Archive"); }
}
Composition. Not sure if this is enough to say that no boilerplate code exists.
class ChildWithUpdateAndArchive : Composite<ChildWithUpdate, ChildWithArchive>
{
public ChildWithUpdateAndArchive(ChildWithUpdate cwu, ChildWithArchive cwa)
: base(cwu, cwa)
{
}
}
Code using all this looks kind of OK, but still unusual (invisible) type casts in assignments. This is a pay off for having less boilerplate code:
ChildWithUpdate b;
ChildWithArchive c;
ChildWithUpdateAndArchive d;
d = new ChildWithUpdateAndArchive(new ChildWithUpdate(), new ChildWithArchive());
//now call separated methods.
b = d;
b.Update();
c = d;
c.Archive();
Here is my version:
interface IGetById
{
T GetById<T>(object id);
}
interface IGetAll
{
IEnumerable<T> GetAll<T>();
}
interface ISave
{
void Save<T>(T item) where T : IHasId; //you can go with Save<T>(object id, T item) if you want pure pure POCOs
}
interface IDelete
{
void Delete<T>(object id);
}
interface IHasId
{
object Id { get; set; }
}
I don't like generic repository interface as it puts additional restrictions and makes it harder to work with it later. I use generic methods instead.
Instead of using header interface for repository I use role interfaces for each repository method. This lets me add additional functionality to repository methods, like logging, publishing changes to PubSub and so on.
I don't use repository for custom queries as I yet didn't find any good and simple querying abstraction that would fit any database. My version of repository can only get item by id or get all items of same type. Other queries is done in memory (if performance is good enough) or I have some other mechanism.
For convenience IRepository interface could be introduced so you would not have to constantly write 4 interfaces for something like crud controllers
interface IRepository : IGetById, IGetAll, ISave, IDelete { }
class Repository : IRepository
{
private readonly IGetById getter;
private readonly IGetAll allGetter;
private readonly ISave saver;
private readonly IDelete deleter;
public Repository(IGetById getter, IGetAll allGetter, ISave saver, IDelete deleter)
{
this.getter = getter;
this.allGetter = allGetter;
this.saver = saver;
this.deleter = deleter;
}
public T GetById<T>(object id)
{
return getter.GetById<T>(id);
}
public IEnumerable<T> GetAll<T>()
{
return allGetter.GetAll<T>();
}
public void Save<T>(T item) where T : IHasId
{
saver.Save(item);
}
public void Delete<T>(object id)
{
deleter.Delete<T>(id);
}
}
I mentioned that with role interfaces i can add additional behavior, here is couple examples using decorators
class LogSaving : ISave
{
private readonly ILog logger;
private readonly ISave next;
public LogSaving(ILog logger, ISave next)
{
this.logger = logger;
this.next = next;
}
public void Save<T>(T item) where T : IHasId
{
this.logger.Info(string.Format("Start saving {0} : {1}", item.ToJson()));
next.Save(item);
this.logger.Info(string.Format("Finished saving {0}", item.Id));
}
}
class PublishChanges : ISave, IDelete
{
private readonly IPublish publisher;
private readonly ISave nextSave;
private readonly IDelete nextDelete;
private readonly IGetById getter;
public PublishChanges(IPublish publisher, ISave nextSave, IDelete nextDelete, IGetById getter)
{
this.publisher = publisher;
this.nextSave = nextSave;
this.nextDelete = nextDelete;
this.getter = getter;
}
public void Save<T>(T item) where T : IHasId
{
nextSave.Save(item);
publisher.PublishSave(item);
}
public void Delete<T>(object id)
{
var item = getter.GetById<T>(id);
nextDelete.Delete<T>(id);
publisher.PublishDelete(item);
}
}
It's not hard to implement in memory store for testing
class InMemoryStore : IRepository
{
private readonly IDictionary<Type, Dictionary<object, object>> db;
public InMemoryStore(IDictionary<Type, Dictionary<object, object>> db)
{
this.db = db;
}
...
}
Finally put all together
var db = new Dictionary<Type, Dictionary<object, object>>();
var store = new InMemoryStore(db);
var storePublish = new PublishChanges(new Publisher(...), store, store, store);
var logSavePublish = new LogSaving(new Logger(), storePublish);
var repo = new Repository(store, store, logSavePublish, storePublish);
You can use the visitor pattern, read an implementation here so you can only implement the necesary functionality.
HereĀ“s the idea:
public class Customer : IAcceptVisitor
{
private readonly string _id;
private readonly List<string> _items = new List<string>();
public Customer(string id)
{
_id = id;
}
public void AddItems(string item)
{
if (item == null) throw new ArgumentNullException(nameof(item));
if(_items.Contains(item)) throw new InvalidOperationException();
_items.Add(item);
}
public void Accept(ICustomerVisitor visitor)
{
if (visitor == null) throw new ArgumentNullException(nameof(visitor));
visitor.VisitCustomer(_items);
}
}
public interface IAcceptVisitor
{
void Accept(ICustomerVisitor visitor);
}
public interface ICustomerVisitor
{
void VisitCustomer(List<string> items);
}
public class PersistanceCustomerItemsVisitor : ICustomerVisitor
{
public int Count { get; set; }
public List<string> Items { get; set; }
public void VisitCustomer(List<string> items)
{
if (items == null) throw new ArgumentNullException(nameof(items));
Count = items.Count;
Items = items;
}
}
So, you can apply separation of concerns between domain logic and infraestructure applying the visitor patter for persistance.
Regards!
i am pretty new to the repository design pattern and i have reached a dead end while trying to implement it, with regards to inheritance.
I am not sure even if i started in the right direction.
So basically i will have an abstract base class Product, with id and imagePath for instance, and will have several products which inherit from this.
namespace Common
{
public abstract class Product
{
public int Id { get; set; }
public string ImgPath { get; set; }
}
public class Scale : Product
{
public int AdditionalProperty { get; set; }
}
}
Now the repositories are as follows:
public class BaseRepository
{
protected TEstEntities1 _dataContext = new TEstEntities1();
public BaseRepository()
{
_dataContext = new TEstEntities1();
}
}
public interface IProductRepository
{
Common.Product Get(int id);
void Add(Common.Product p);
void Update(Common.Product p);
List<Common.Product> ListAll();
}
public class ProductRepository : BaseRepository, IProductRepository
{
public Common.Product Get(int id)
{
throw new NotImplementedException();
}
public void Add(Common.Product p)
{
throw new NotImplementedException();
}
public void Update(Common.Product p)
{
throw new NotImplementedException();
}
public List<Common.Product> ListAll()
{
throw new NotImplementedException();
}
}
My problem is as follows: how do i integrate operations regarding Scale ? It seems a bad idea to add something like Add(Common.Scale s) to the IProductRepository. It seems like a bad idea to see inside the Add(Common.Product p) which type of Product i try to add, then cast to it, then add.
I guess that if i were to describe this problem more thoroughly, I want to repeat as few code as possible, to somehow isolate base product adding/removing code in the product repository, and somehow put e.g. Scale specific code for adding/removing inside another class, or method.
A more thorough approach of mine has been this one:
public interface IProductRepository<T> where T : Common.Product
{
T Get(int id);
void Add(T p);
void Delete(T p);
}
public abstract class ProductRepository : BaseRepository
{
protected void Add(Common.Product p)
{
_dataContext.AddToProduct(new Product { Id = p.Id, Image = p.ImgPath });
_dataContext.AcceptAllChanges();
}
protected void Delete(Common.Product p)
{
var c = _dataContext.Product.Where(x => x.Id == p.Id).FirstOrDefault();
_dataContext.DeleteObject(c);
_dataContext.AcceptAllChanges();
}
protected Product Get(int id)
{
return _dataContext.Product.Where(x => x.Id == id).FirstOrDefault();
}
}
public class CantarRepository : ProductRepository, IProductRepository<Common.Scale>
{
public void Add(Common.Scale p)
{
base.Add(p);
_dataContext.Scale.AddObject
(new Scale { ProductId = p.Id, AdditionalProperty = p.AdditionalProperty });
_dataContext.AcceptAllChanges();
}
public void Delete(Common.Scale p)
{
var c = _dataContext.Scale.Where(x => x.ProductId == p.Id);
_dataContext.DeleteObject(c);
_dataContext.AcceptAllChanges();
base.Delete(p);
}
public new Common.Scale Get(int id)
{
var p = base.Get(id);
return new Common.Scale
{
Id = p.Id,
ImgPath = p.Image,
AdditionalProperty = _dataContext.Scale.Where
(c => c.ProductId == id).FirstOrDefault().AdditionalProperty
};
}
}
Unfortunatelly this falls short for one reason.
If i use a factory pattern to return an IProductRepository and inside it i instantiate with IProductRepository this will not work because of covariance and contravariance, and IProductRepository can't be contravariant and covariant at the same time, and splitting the methods into two interfaces seems counterintuitive and cumbersome.
I suspect i will need the factory pattern in order to have a base class interface returned, but i am open to suggestions on this as well. As i've said, i am very newbie regarding the repo pattern.
I am curious as to what i am doing wrong, how i can solve this, and how can i implement this better.
Thanks.
You are using inheritance incorrectly. You cannot treat Scale as a (is-a) Product if the important difference is additional properties - that makes the exposed interface of Scale different than Product, and at that point inheritance simply gets in your way. Use inheritance to share behavior, not properties.
What problem are you trying to solve with your use of inheritance?
I want to repeat as few code as
possible
Wouldn't it be better to have a little duplication in order to get things done, rather than spin your wheels trying to work with an implausible design?
Also, this is all you are sharing with your inheritance:
public int Id { get; set; }
public string ImgPath { get; set; }
Repeating the definition of two auto-implemented properties almost doesn't even qualify as duplication, it most certainly is not an issue to be concerned about.
Misusing inheritance, however, is fairly grievous. The next person to maintain your app will curse you for it.
So basically i will have an abstract
base class Product, with id and
imagePath for instance, and will have
several products which inherit from
this.
So when you add new types of products you will have to extend an inheritance hierarchy? That seems like a bad idea.
I'm not a big fan of generic repository but after looking at your code I think you should use it:
public interface IEntity
{
int Id { get; }
}
public interface IRepository<T> where T : class, IEntity
{
IQueryable<T> GetQuery();
T Get(int id);
void Add(T entity);
void Update(T entity);
void Delete(T entity);
}
implementation:
public Repository<T> where T : class, IEntity
{
private ObjectSet<T> _set; // or DbSet
private ObjectContext _context; // or DbContext
public Repository(ObjectContext context) // or DbContext
{
_context = context;
_set = context.CreateObjectSet<T>(); // _context.Set<T>() for DbContext
}
public IQueryable<T> GetQuery()
{
return _set;
}
public T Get(int id)
{
return _set.SingleOrDefault(e => e.Id == id);
}
public void Add (T entity)
{
_set.AddObject(entity);
}
public void Update(T entity)
{
_set.Attach(entity);
context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
// or context.Entry(entity).State = EntityState.Modified; for DbContext
}
public void Delete(entity)
{
_set.Attach(entity);
_set.DeleteObject(entity);
}
}
There is NO AcceptAllChanges because it will reset ObjectStateManager and your changes will never be saved. There is no recreation of objects because it doesn't make sense.
Using this repository is as simple as:
var repo = new BaseRepository<Product>(context);
repo.Add(new Product() { ... });
repo.Add(new Scale() { ... }); // yes this works because derived entities are handled by the same set
context.Save();
I recently implemented something like this. (Using your sample types names) I have a single ProductRepository which knows how to persist/unpersist all Product subtypes.
Ultimately, your backing data store will have to have the ability to store the various subtypes and any properties which they introduce. Your repository type will also have to know how to take advantage of those features for each given subtype. Therefore, each time you add a subtype, you will have work involved in, for example, adding table columns to your backing data store to hold properties it may introduce. This implies that you will also need to make the appropriate changes to your repository type. It seems easiest, therefore, to examine the type of the entity when passed to your repository type and throw an exception if it is not a supported type since there's nothing else your repository will be able to do with it. Similarly, when retrieving the list of entities, the repository will have to know how to retrieve each entity subtype and construct an instance. Since these all derive from Product, they can all form items an in IEnumerable<Product> return value.
I am trying to use the repository pattern for a site made in .Net 2.0. All client code is expecting datatable for binding and I am not going to be able to change that, so please bear with me.
I am having a (probably dumb) issue. I cannot figure out how to pass a strongly typed entity to my concrete repository. The interface is forcing me to pass an Employee type but I need to pass a Developer type (it derives from Employee) because it has specific properties not found in the base class.
public interface IEmployeesRepository
{
DataTable Employees { get; }
void SaveEmployee(Employee employee);
void DeleteEmployee(Employee employee);
}
public class DevelopersRepository : IEmployeesRepository
{
public void SaveEmployee(Developer employee)
{
Database db = new SqlDatabase(connectionString);
DbCommand dbCommand = db.GetStoredProcCommand("Developers_Insert", employee.ProgrammingLanguage);
db.ExecuteNonQuery(dbCommand);
}
}
}
I tried using generics instead but then I still will not have a strongly typed object right?
I could be wrong but it sounds like you want to use a generic constraint:
public interface IEmployeeRepository<T>
where T : Employee
{
DataTable Employees { get; }
void SaveEmployee(T employee);
void DeleteEmployee(T employee);
}
public class DevelopersRepository : IEmployeeRepository<Developer>
{
public void SaveEmployee(Developer employee)
{
Database db = new SqlDatabase(connectionString);
DbCommand dbCommand = db.GetStoredProcCommand("Developers_Insert", employee.ProgrammingLanguage);
db.ExecuteNonQuery(dbCommand);
}
}
DevelopersRepository implements IEmployeesRepository so it must implement all methods in the interface.
public void SaveEmployee(Employee employee)
{
if (!(employee is Developer)) throw new Exception("...");
...
}