C# Interfaces implementation - c#

I don't know how manage properly the interfaces in C#. My goal is to have an abstract class for my Business Layer Services that have some common methods (like Save(), Dispose()), that call different DAL repository methods. I wish to avoid to repeat in all my services something like:
public Save()
{
repository.Save();
}
I have a scenario similar to that:
Interface
namespace Common
{
public interface IRepository
{
void Save;
void Dispose;
}
}
DAL
namespace DAL
{
public Repository : IRepository
{
public void Save() {};
public void Dispose() {};
public void Add() {}
}
}
BL
namespace BL
{
public abstrac BaseService
{
protected IRepository repository;
protected BaseService(IRepository repo)
{
repository = repo;
}
public Save()
{
repository.Save();
}
}
//...
//Tentative 1
public Service : BaseService
{
private Repository rep;
public Service()
: base(new DAL.Repository())
{
rep = base.repository; // ERROR: cannot convert IRepository to Repository
}
}
}
I tried also this:
//Tentative 2
public Service : BaseService
{
private IRepository rep;
public Service()
: base(new DAL.Repository())
{
rep = base.repository; // OK
}
public void Add()
{
rep.Add() // ERROR: IRepository doesn't contain a definition for 'Add'
}
}
I know I could define in the interface all the methods I want to use, but I'll will have to manage a lot of problems with generic types and, as you should have understand from my question, I'm quite new in C# and I wish to avoid complexity is is possible, utill I'll be more expert at least :)

Firstly I think you're having a name clash with you member
IRepository rep.
Try using
DAL.IRepository rep
The reason that you're getting an error is that you've defined "Add" as something unique to "Repository". Your member variable is an "IRepository" allowing you to put anything that implements "IRepository" onto it.
Just because you CAN put a Repository into it, doesn't mean that everything on it is going to be a repository. (Think of it look good 'ol fingers and thumbs, all thumbs are fingers, but not all fingers are thumbs)
If you NEED to call add on any repository, then add it to the interface. Else, you need to decide whether or not that member should be IRepository or Repository.
Alternatively, you COULD use
Repository myRep = rep as Repository;
if(rep!=null)
{
myRep.Add();
...
profit();
}

public Service()
: base(new DAL.Repository())
{
rep = (Repository)base.repository;
}
This way u will get the Add() service which is not a part of IRepository but a newer implementation in the extended class.

Seeing as your main problem is the lack of accessibility to the Add method, and seeing as this is a relative common method anyway, I would firstly recommend adding it to your IRepository, so it looks like this:
public interface IRepository
{
void Add();
void Save();
void Dispose();
}
You would then implement your appropriate repositories whilst inheriting from IRepository. Now, understandably you may want to be able to access custom methods on a Repository. In order to resolve this what you could do is have your BaseService accept a generic repository:
public BaseService<T> where T : IRepository
{
protected T repository { get; set; }
protected BaseService(T repo)
{
repository = repo;
}
}
Then a service would look like this
public UserService : BaseService<UserRepository>
{
public UserService() : base(new DAL.UserRepository())
{
// base.Repository is now a UserRepository.
}
}
With this implementation your UserService will be able to access all of the methods that UserRepository exposes, as it's strongly typed with the generic. Hope this helps.

Related

Is it a good practice to cast from an interface to some concrete class when needed?

I'am developing a small system and i developed the classic generic repository. For now, i have the following architecture for my DAL.
public interface IRepositorio<T> where T : class
{
T Get(long id);
long Insert(T obj);
bool Update(T obj);
bool Delete(T obj);
}
public abstract class Repositorio<T> : IRepositorio<T> where T : class
{
public IDbConnection Connection
{
get
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["DBFila"].ConnectionString);
}
}
public T Get(long id)
{
//...
}
public long Insert(T obj)
{
//...
}
public bool Update(T obj)
{
//...
}
public bool Delete(T obj)
{
//...
}
}
My concrete repository looks like this:
public class FilaRepositorio : Repositorio<FilaRepositorio>
{
public FilaRepositorio()
{
}
public void SomeCustomMethod()
{
// Some custom method
}
}
I am also using Simple Injector to follow the IoC and DI patterns, for this reason, when i try to call "SomeCustomMethod()" i dont have access to it (obviously). Look:
public class Processador
{
private IRepositorio<FilaModel> _repoFila;
public Processador(IRepositorio<FilaModel> repoFila)
{
_repoFila = repoFila;
}
public void Processar()
{
_repoFila.SomeCustomMethod(); // <-- wrong
((FilaRepositorio)_repoFila).SomeCustomMethod();// <-- works
}
}
Given this i have some questions:
Is a good or acceptable practice to make that cast (FilaRepositorio)?
If its not a good practice, how to write good code for this case?
There are a few options available. The main problem with making the cast is that it is an implementation concern.
What would happen if the injected object was not a FilaRepositorio?
By making the cast you are tightly coupling the class to an implementation concern that is not guaranteed to be the inject dependency. Thus the constructor is not being entirely truthful about what it needs to perform its function.
This demonstrates the need to practice Explicit Dependencies Principle
The Explicit Dependencies Principle states:
Methods and classes should explicitly require (typically through
method parameters or constructor parameters) any collaborating objects
they need in order to function correctly.
One way to avoid it would be to make a derived interface that explicitly exposes the desired functionality of its dependents.
public interface IFilaRepositorio : IRepositorio<FilaModel> {
void SomeCustomMethod();
}
public class FilaRepositorio : Repositorio<FilaModel>, IFilaRepositorio {
public void SomeCustomMethod() {
//...other code removed for brevity.
}
}
and have the Processador depend on that more targeted abstraction.
Now there is no need for the cast at all and the class explicitly expresses what it needs.
public class Processador {
private readonly IFilaRepositorio _repoFila;
public Processador(IFilaRepositorio repoFila) {
_repoFila = repoFila;
}
public void Processar() {
_repoFila.SomeCustomMethod(); // <-- works
}
}
If you need to access a specific method from any part of your application, then that specific method must be part of your abstraction, or else there is no guarantee that you may use it when changing the concrete class.
I do not believe that your use of casting is a good idea at all, what is usually done in this case is to create a specific interface which defines any other method you could need to use:
public interface IFilaRepositorio : IRepositorio<Fila>
{
void SomeCustomMethod();
}
And than use and declare that specific interface in any part of your code where you believe you need to use it:
public class Processador
{
private IFilaRepositorio _repoFila;
public Processador(IFilaRepositorio repoFila)
{
_repoFila = repoFila;
}
public void Processar()
{
_repoFila.SomeCustomMethod();
}
}

Class which supports injectable mocked object but also using statement c#

How do I go about creating a class which wraps all EF repository calls in a Using statement whilst also supporting an injectable interface of the repository?
I can't seem to wrap my head around having this class support 2 different types of instantiation.
public class MyClass(IRepo repo)
{
_repo = repo;
}
public void MyMethod()
{
using ( var db = new DbContxt() )
{
var repo = new Repo(db);
repo.GetById(1);
}
}
In essence, the life-time of the 'db' object is the lifetime of the method call. Whereas the lifetime of 'db' would be managed outside of the class if injected.
You could structure it this way:
public class MyClass
{
private readonly IRepo _repo;
//or if you want a parameterless constructor...
public MyClass() : this(new Repo()) { }
public MyClass(IRepo repo)
{
_repo = repo;
}
public MyObject MyMethod(int id)
{
_repo.GetById(id);
}
}
public interface IRepo
{
MyObject GetById(int id);
}
public class Repo : IRepo
{
public MyObject GetById(int id)
{
using ( var db = new DbContext())
{
//do your db related stuff here
}
}
}
You would need a way of injecting an instance of Repo into MyClass so maybe take a look at IoC.
This way, you can easily mock IRepo for testing purposes.
You shouldn't do it that way. Have a parameterless constructor for your Repo, and instantiate the DbContext there. You can also have an overload for it that takes a DbContext, but you don't have to go about it that way. The point is to let each layer only worry about what it needs on its own. Let the IOC container inject everything as it is created, don't make objects for a different layer inside your methods.

Implementing the strategy pattern with generics and StructureMap

I am trying to implement the strategy pattern in my repository layer using SM and generics. For that I have an interface, IPocoRepository, which has a concrete implementation using Entity Framework. This I have managed to wire up in my Bootstrapper-file:
For(typeof(IPocoRepository<>)).Use(typeof(EntityFrameworkRepository<>));
The problem appears when I try to implement caching for this interface. In my cached class I want an instance of the base repository class, so that I can keep my design DRY. Let me outline how these three files look:
public interface IPocoRepository<T>
{
IQueryable<T> GetAll();
...
public class EntityFrameworkRepository<T> : IPocoRepository<T> where T : class
{
public IQueryable<T> GetAll()
{
...
public class CachedRepository<T> : IPocoRepository<T> where T : class
{
private IPocoRepository<T> _pocoRepository;
public CachedRepository(IPocoRepository<T> pr)
{
_pocoRepository = pr;
}
public IQueryable<T> GetAll()
{
var all = (IQueryable<T>)CacheProvider.Get(_cacheKey);
if (!CacheProvider.IsSet(_cacheKey))
{
all = _pocoRepository.GetAll();
...
Edit: I want StructureMap to return CachedRepository when IPocoRepository is requested, except when requested for in CachedRepository - then I want it to return EntityFrameworkRepository.
I know this is simple when dealing with non-generic classes:
For<ICountyRepository>().Use<CachedCountyRepository>()
.Ctor<ICountyRepository>().Is<CountyRepository>();
I tried searching the documentation for how to do this, but couldn't find anything. Any help would be appreciated!
Ok, this isn't too hard. You can use a type interceptor. Given you have the following classes:
public interface IRepository<T>{}
public class Repository<T>:IRepository<T>{}
public class RepositoryCache<T> : IRepository<T>
{
private readonly IRepository<T> _internalRepo;
public RepositoryCache(IRepository<T> internalRepo)
{
_internalRepo = internalRepo;
}
public IRepository<T> InternalRepo
{
get { return _internalRepo; }
}
}
You will then need to create a type interceptor. You can use the configurable "MatchedTypeInterceptor" provided by StructureMap for this. The interceptor will need to look for your repositories and then figure out what the generic type parameters are. Once it has the type parameters it can declare the type of cache it needs and initialize it. As part of the initialization, it will take the original repository in it's constructor. Then the interceptor will return the completed cache to whatever requested it from the ioc context. Here is the complete sequence inside a test.
This can be moved out into your registry, I just left it all together as an minimal example.
[Test]
public void doTest()
{
MatchedTypeInterceptor interceptor = new MatchedTypeInterceptor(
x => x.FindFirstInterfaceThatCloses(typeof (IRepository<>)) != null);
interceptor.InterceptWith(original =>
{
Type closedType = original.GetType()
.FindFirstInterfaceThatCloses(typeof(IRepository<>));
var genericParameters = closedType.GetGenericArguments();
var closedCacheType = typeof(RepositoryCache<>)
.MakeGenericType(genericParameters);
return Activator.CreateInstance(closedCacheType, new[] {original});
});
ObjectFactory.Initialize(x =>
{
x.For(typeof (IRepository<>)).Use(typeof (Repository<>));
x.RegisterInterceptor(interceptor);
});
var test = ObjectFactory.GetInstance<IRepository<int>>();
Assert.That(test is RepositoryCache<int>);
}

How should I write unit tests for multiple implementations of an interface, while adhering to DRY?

I have multiple classes that implement the same interface, how should I write unit tests to verify that each class implements the interface correctly, keeping code duplication to a minimum (DRY)?
As an example of what I mean, the following is a very basic library containing two implementations of IDeleter: Deleter1 and Deleter2. Both implement the method Delete by calling Delete on their associated IRepository.
using Microsoft.Practices.Unity;
namespace TestMultiple
{
public interface IRepository
{
void Delete(string id);
}
public abstract class Baseclass
{
protected abstract IRepository GenericRepository { get; }
public void Delete(string id)
{
GenericRepository.Delete(id);
}
}
public interface IDeleter
{
void Delete(string id);
}
public interface IRepository1 : IRepository
{
}
public abstract class RepositoryBase
{
public void Delete(string id)
{
}
}
public class Repository1 : RepositoryBase, IRepository1
{
}
public class Deleter1 : Baseclass, IDeleter
{
protected override IRepository GenericRepository { get { return Repository; } }
[Dependency]
public IRepository1 Repository { get; set; }
}
public interface IRepository2 : IRepository
{
}
public class Repository2 : RepositoryBase, IRepository2
{
}
public class Deleter2 : Baseclass, IDeleter
{
protected override IRepository GenericRepository { get { return Repository; } }
[Dependency]
public IRepository2 Repository { get; set; }
}
}
For these two classes, Deleter1 and Deleter2, I have written two corresponding unit test classes as shown in the below snippet. The tests check the same behaviour, i.e. that Delete is called on the underlying repository. Is there some better way to implement the same tests for all implementations of IDeleter? For example, should I write a baseclass containing common test methods, such as TestDelete, for TestDeleter1 and TestDeleter2?
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Practices.Unity;
using Moq;
namespace TestMultiple.Tests
{
[TestClass]
public class TestDeleter1
{
[TestMethod]
public void TestDelete()
{
var mockRepo = new Mock<IRepository1>();
var container = new UnityContainer().RegisterInstance<IRepository1>(mockRepo.Object);
var deleter = container.Resolve<Deleter1>();
deleter.Delete("id");
mockRepo.Verify(r => r.Delete("id"));
}
}
[TestClass]
public class TestDeleter2
{
[TestMethod]
public void TestDelete()
{
var mockRepo = new Mock<IRepository2>();
var container = new UnityContainer().RegisterInstance<IRepository2>(mockRepo.Object);
var deleter = container.Resolve<Deleter2>();
deleter.Delete("id");
mockRepo.Verify(r => r.Delete("id"));
}
}
}
EDIT:
Feel free to mention unit test frameworks that may help solve this kind of problem, although my preference is with NUnit.
There's no easy way to write tests in the frameworks I'm aware of that assert common behaviour on interfaces. The best you can do is write tests and helper methods as if you were testing an abstract class and then insert the real type into derived test classes.
For example, you could create an DeleterTests class, which provides tests for the interface:
public abstract class DeleterTests<TRepository> where TRepository : IRepository
{
[TestMethod]
public void TestDelete()
{
var mockRepo = new Mock<TRepository>();
var container = new UnityContainer();
container.RegisterInstance<TRepository>(mockRepo.Object);
var deleter = this.CreateDeleter(container);
deleter.Delete("id");
mockRepo.Verify(r => r.Delete("id"));
}
protected abstract IDeleter CreateDeleter(IUnityContainer container);
}
Then, you inherit from this class for anything implementing IDeleter, implementing the abstract CreateDeleter method as you need to:
public class Deleter1Tests : DeleterTests<IRepository1>
{
protected override IDeleter CreateDeleter(IUnityContainer container)
{
return container.Resolve<Deleter1>();
}
}
public class Deleter2Tests: DeleterTests<IRepository2>
{
protected override IDeleter CreateDeleter(IUnityContainer container)
{
return container.Resolve<Deleter2>();
}
}
If you needed to compose the instances differently, you could implement the abstract CreateDeleter in any fashion.
You should write unit test for each class, not really worrying about other implementations. If you feel like you write the same tests again and again, it is propably because your production code is un-DRY -- not your test code. As others have pointed out; if the different implementations have a lot in comon, some common abstract ancestor is probably a good idea.
If all of your classes should implement the IDeleter interface identically, your base class should not be abstract. Implement the IDeleter interface in the base class, that way all of the child classes inherit the same implementation from the base. If there is an edge case where a different implementation is desired, that class can then override the base class' implementation.

How to figure out which repository to call for different implementations of an interface?

I am just starting in DDD and have a question regarding interfaces of objects and repositories. Suppose I have the following objects
public interface IPerson { ... }
public class Student
{
double gpa;
...
}
public class Teacher
{
double salary; ...
}
then I also have two repositories such as
public class StudentRepository :IRepository { public void Save(Student) }
public class TeacherRepository :IRepository { public void Save(Teacher) }
My question is, suppose I have a list of IPerson objects called persons, is there a way where I can just do something like repository.Save(persons) ? Without having to use reflection to figure out what type the IPerson actually is.
I currently have another class
PersonRepository :IRepository
{
public void Save(IPerson person)
{
if(Person is Student)
{
new StudentRepository.Save(person as Student);
}
else if(Person is Teacher)
{ ....}
}
}
Then I can call personRepository.Save(persons);
However this doesnt feel like an optimal way to structure things. How can I improve this design?
Thanks
EDIT:
What I'm looking for is, say I receive an IPerson object called person. I do not necessarily know what implementation it is, I just want to call repository.Save(person) and have it call the correct repository. Is there a way to do this without using some sort of switch statement with reflection?
Consider using generic repository
class Repository<T> :IRepository<T>
{
public void Save(T entity)
{
...
}
}
Usage
IRepository<Student> repo1 = new Repository<Student>();
repo1.Save(new Student());
IRepository<Teacher> repo2 = new Repository<Teacher>();
repo2.Save(new Teacher());
Next you can use IoC container and DI just to pass repositories around instead of creating them
At the top level, say in the main method or global.asax
IRepository<Student> studentRepo = IoC.Current.Resolve<IRepository<Student>>();
Later in a class that needs to save data, pass IRepository<Student> studentRepo into constructor
class Foo
{
private IRepository<Student> repo
Foo(IRepository<Student> repo)
{
this.repo = repo;
}
public void Save(Student s)
{
repo.Save(s);
}
}
EDIT
You can move a save operation to the IPerson<T>
class Person<T> : IPerson<T>
{
private IRepository<T> repo;
Person(IRepository<T> repo)
{
this.repo = repo;
}
public void Save()
{
repo.Save<T>();
}
}
So when you derive Teacher and Student from Person<T> you pass correspondent T, like
class Student : Person<Student>
{
private IRepository<Student> repo;
Person(IRepository<Student> repo):base(repo)
{
...
}
}
This shall give you the ability to work with List without Reflection or switch kung fu.
You can potentially have a method with C# generics
interface Repository<TEntity> where TEntity : class {
void Save(TEntity entity);
}
But I would discourage having generic (as in generalized, not C# generics) repositories. Repository interface should be domain driven and specific to your entity. Please consider this article by Greg Young.
It is also not clear why you have interfaces for you entities (IPerson). Interfaces are usually created at the seam of the application. Are you planning to have more than one implementation of IPerson?
Two possible approaches.
First, interfaces specific for domain types
interface IStudentRepository
interface ITeacherRepository
class StudentRepository : IStudentRepository
class TeacherRepository : ITeacherRepository
Second, a generic interface
interface IRepository<T>
class StudentRepository : IRepository<Student>
class TeacherRepository : IRepository<Teacher>

Categories