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.
Related
I have two operations to be done. One is for Air transport and one for Road transport. both processes some message.
Here is the Interface
public interface IProcess
{
void Process(string message);
}
Here is my implementation of Road transport
public class RoadTransport: IProcess
{
public void Process(string msg)
{
// do some road related operation
}
}
Here is my implementation of Air transport
public class AirTransport: IProcess
{
public void Process(string msg)
{
// do some air related operation
}
}
Now, I will show the factory class, which will return different objects based on ID
public class MyFactory
{
private readonly AirTransport airtransport = null;
private readonly RoadTransport roadtransport = null;
public MyFactory(AirTransport, RoadTransport)// dependency injected
{
airtransport = AirTransport;
roadtransport = RoadTransport;
}
IProcess process = null;
public IProcess GetInstance(int id)
{
swicth(id)
{
case "1":
process = airtransport;
break;
case "2":
process = roadtransport;
break;
}
return process;
}
}
Here is my class which supposed to be tested
public class HomeController:Controller
{
private readonly MyFactory _myfactory;
private readonly MyConfigurations _myConfigurations;
public HomeController(MyFactory factory, MyConfigurations configurations)
{
_myfactory = factory;
}
public IActionResult Index()
{
return View();
}
Public ActionResult Process(string message, string id)
{
var configurations = _myConfigurations;
if(configurations!=null)
{
IProcess processor= _myfactory.GetInstance(id);
processor.Process(message);
return View("Index");
}
}
}
How do I unit test this controller, because there is no interface defined for factor class? do I have to mock the factory class or is it wrong design?
do I have to mock the factory class
NO. Do not mock implementation concerns, mock abstractions.
or is it wrong design?
It is not a flexible design as your classes are tightly coupled to concretions/implementation concerns that do not lend itself well to isolated unit tests.
How do I unit test this controller, because there is no interface defined for factor class?
Then define an abstraction (contract) for the factory. (Could be an interface or abstract class)
public interface IProcessFactory {
IProcess GetInstance(int id);
}
and have the implementation derive from the abstraction
public class MyFactory : IProcessFactory {
//...
}
The controller can now be refactored to explicitly depend on the abstraction via constructor injections.
public class HomeController : Controller {
private readonly IProcessFactory factory;
private readonly MyConfigurations configurations;
public HomeController(IProcessFactory factory, MyConfigurations configurations) {
this.factory = factory;
this.configurations = configurations;
}
//...omitted for brevity
}
This now allows for a mock to be substituted when testing the controller in isolation.
The assumption is that MyConfigurations is a POCO storing settings/options that does not fall under functional concerns that require abstraction.
The final step would be to ensure that the actual derived factory implementation is injected into the controller in production.
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.
I've found that in my UnitOfWork I have a repository for each type of entity and am not using aggregate roots, so I'm trying to fix that. Tackling the idea of computer inventory, I currently have my UnitOfWork structured as such:
public class UnitOfWork : IUnitOfWork
{
private readonly ReportingDbContext _dbContext = null;
public UnitOfWork()
{
_dbContext = new ReportingDbContext();
}
public void Commit()
{
_dbContext.SaveChanges();
}
// Inventory
public IRepository<ComputerEntity> Computers {get { return new Repository<ComputerEntity>(_dbContext); }}
public IRepository<NetworkAdapterEntity> NetworkAdapters { get { return new Repository<NetworkAdapterEntity>(_dbContext); } }
// plus a bunch more
}
I want only my aggregate root to appear there, which should be easy enough to do. I think the issue is that I'm using a single repository class and feeding in the type when I new it up. I believe the answer is to have multiple repositories, each one corresponding to an aggregate root. What is nice about this one generic repository that I'm using for each type is that it handles all my Entity Framework stuff like finding by ID, saving to the DbSet, etc. My generic repository is setup as such:
public class Repository<T> : IRepository<T> where T : class
{
protected DbContext DbContext { get; set; }
protected DbSet<T> DbSet { get; set; }
public Repository(DbContext dbContext)
{
if (dbContext == null)
{
throw new ArgumentNullException("dbContext");
}
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
public IQueryable<T> GetAll()
{
return DbSet;
}
public IQueryable<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
return DbSet.Where(predicate);
}
// the rest of the implementation omitted for brevity
}
This repository uses an interface that all my yet-to-be-created aggregate root repositories should use:
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
T GetById(int id);
void Remove(T entity);
void Add(T newEntity);
}
Now here is the real meat of the question. I have the above interface implemented nicely in my concrete Repository class, and I want that same functionality in all the aggregate root repositories that I will be making. I don't want to ever directly use this generic repository, as I just want to use it for a base to get at the basic CRUD stuff it does with Entity Framework. I don't want to repeat the already implemented generic repository stuff, just inherit it. More importantly, I want to design this correctly the first time.
Would it be appropriate to create my aggregate root based repository as such:
public interface IComputerRepository
{
string ComputerSpecificMethod(string param);
}
public class ComputerRepository : Repository<ComputerEntity>, IComputerRepository
{
public ComputerRepository(DbContext dbContext) : base(dbContext)
{
//
}
public string ComputerSpecificMethod(string param)
{
// do stuff
return "test";
}
}
Then use this new fancy repository (and others like it) in my UnitOfWork as such:
public IRepository<ComputerEntity> Computers {get { return new ComputerRepository(_dbContext); }}
Instead of:
public IRepository<ComputerEntity> Computers {get { return new Repository<ComputerEntity>(_dbContext); }}
The goal is to stick to the UnitOfWork/Repository pattern, and I'm unsure if this is the proper way of doing this.
I found that the way to do this that works for me is to have the interface for each custom repository in my unit of work class as such:
public IInventoryRepository Computers { get { return new InventoryRepository(_dbContext); } }
It is implemented in its own class of course. To get it to inherit properly, I did this:
public class InventoryRepository : GenericRepository<ComputerEntity>, IInventoryRepository
{
public InventoryRepository(DbContext dbContext) : base(dbContext)
{
}
// your custom methods go here
}
I then can use this in my WCF service as such:
using (var uoW = new UnitOfWork())
{
var repo = uoW.Computers;
var computerEntity = repo.FindComputerByHostname(hostname, client);
// do more stuff
}
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.