I have an asp.net-mvc website and i am using ninject for IOC and nhibernate for my ORM mapping
Here is my IOC binding code:
internal class ServiceModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IIntKeyedRepository<>)).To(typeof(Repository<>)).InRequestScope();
}
}
and here is an example of how I am doing IOC into my controller code:
public FAQController(IIntKeyedRepository<FAQ> faqRepository, IUnitOfWork unitOfWork)
{
_faqRepository = faqRepository;
_unitOfWork = unitOfWork;
}
The issue is that up until now, each controller had a single table that it was pointing to so i only needed on repository class passed into it...
Now, I have a number of tables and classes that are all just have 2 fields:
- Id
- Name
for each of these classes, i simply inherit from a base class called:
BaseModel
which is just:
public class BaseModel
{
public virtual string Name { get; set; }
public virtual int Id { get; set; }
}
I want to have one:
StaticDataController
class that can do all of the CRUD for every class that simply inherits from BaseModel (with no extra fields)
The dumb simple way would be to do this:
private readonly IIntKeyedRepository<Object1> _object1Repository;
private readonly IIntKeyedRepository<Object2> _object2Repository;
private readonly IIntKeyedRepository<Object3> _object3Repository;
private readonly IIntKeyedRepository<Object4> _object4Repository;
private readonly IIntKeyedRepository<Object5> _object5Repository;
public StaticDataController(IIntKeyedRepository<Object1> obj1Repository, IIntKeyedRepository<Object2> obj2Repository, IIntKeyedRepository<Object3> obj3Repository, IIntKeyedRepository<Object4> obj4Repository, IIntKeyedRepository<Object5> obj5Repository)
{
_obj1Repository= obj1Repository;
_obj2Repository= obj2Repository;
_obj3Repository= obj3Repository;
_obj4Repository= obj4Repository;
_obj5Repository= obj5Repository;
}
Since I am passing the table in as a parameter to my methods, I would have to have some switch statement in my controller to get the right repository class based on the string of the parameter.
I assume there must be a much more elegant way to support what I am trying to do so I wanted to see if there is any best practice here (controller inheritance, reflection, etc.)?
If you need to do this it means that your controller does too many things and a strong indication that it requires a service layer. In this case I deport those repositories into the service layer. So my controller takes a service instead of multiple repositories:
The service has business that could be composed of multiple atomic repository CRUD methods.
I know that you might say: yes, but now I have to inject all those repositories into the implementation of the
IStatisticDataService
interface. Yes, but it would make more sense to aggregate those atomic CRUD operations into the service layer rather than the controller.But if need 5 or more repositories in order to perform a some business operations, maybe you have to rethink your domain architecture. Probably you could use composition in your domain models and define relations between them in order to reduce the number of repositories. It's difficult to provide more concrete advice without knowing the specifics of your domain.
Great, make them derive all from the same base domain model and have a single repository to serve them. You could use descriminator columns, etc...
As Mark Seemann mentioned: "It's quite OK, but once you feel that the Controller becomes too cluttered, you can refactor its dependencies to an Aggregate Service."
Look at: BestPractices: Is it acceptable to use more than one repository in a MVC-Controller?
Darin is absolutely right. I'd just like to add though, if you're using MVC 3, you should be using the Ninject.MVC3 nuget package rather than creating your own Service Module.