views:

46

answers:

3

I'm trying to clean my code to make it unit-testable. I know that unit tests must be created while coding but... I have to do it now, with code completed.

My business class is full of methods with a similar implementation like:

var rep=new NHrepository<ModelClass1>(Session);
rep.Where(x=>x.Field1==1).ToList();

first error (from my point of view) is that I don't have to use "new" but instead use DI and add in the ctor parameters a INHrepository modelClass1Repository.

If in my class I have two or more repository of different model class? Each must be in the ctor? Or probably business class is not build with SeparationOfConcern principle?

+1  A: 

You're right about the dependecy injection.

Also, I strongly recommend that you read Working Effectively with Legacy Code if you plan to write unit tests for your legacy code.

Bruno Rothgiesser
+1  A: 

One widely used approach is to have n repositories as parameters to your constructors as you already suspected

Another commonly used approach is to use a dependency injection framework such as Ninject. This allows you to write things like:

[Inject]
public IAbstractRepository<Company> companiesRepository { get; private set; }

[Inject]
public IAbstractRepository<User> usersRepository { get; private set; }

You can then have Ninject inject the appropriate implementation of your interface depending on the usage scenario (e.g. a fake repository for testing or a real repository for production)

Adrian Grigore
I think that this is not a right approach because a property can be leaved "not set" but a ctor parameter cannot. In my case a repository MUST be set so I assume is better to leave it in the ctor.
Mauro Destro
I think you are misunderstanding the code example I gave above. In the example above the repositories would always be automatically instantiated (in other words set) automatically by Ninject whenever you instantiate an obect containing those properties. There is no way to forget to instantiate your repositories. I can't really see any major differences to instantiating them via the constructor except that it's less effort and keeps your code a bit more flexible.
Adrian Grigore
A: 

Your business class should have a contructor with 2 parameters, one for each repository. Your business should expose 2 interfaces, and your persistence should provide their implementations.

bloparod