Reputation: 15866
I have following;
interface IRepository
--interface IRepositoryEF: IRepository
--interface IRepositoryNH: IRepository
----interface ICategoryRepositoryEF: IRepositoryEF
----interface ICategoryRepositoryNH: IRepositoryNH
I want to use CategoryRepositoryEF
and CategoryRepositoryNH
classes in the service. How can I inject them into CategoryService?
CategoryService(IRepository repository)
{
}
What is the best practice about this? Could I use a RepositoryFactory
and inject it into service and then create repositories in the services?
I mean something like following;
CategoryService(CategoryRepositoryFactory factory)
{
var CategoryRepositoryEF = factory.Create("EF");
var CategoryRepositoryNH = factory.Create("NH");
}
Is this good idea? Or I m completely wrong?
Upvotes: 0
Views: 478
Reputation: 101166
The idea is a bit off.
the purpose of repository interfaces is to abstract away the data source. the goal is to allow all using classes to fetch information without knowing where the data comes from. But in your case you force the classes to know wether NHibernate or EntityFramework is used. Why?
I also wouldn't have a IRepository
interface, as you create specific interfaces.
Now the question is rather "How do I map a nhibernate or entity framework repository to one of my interfaces".
That should be done when the application starts. You typically do something like this:
container.Register<ICategoryRepostitory, NHCategoryRepository>();
container.Register<IUserRepostitory, EFUserRepository>();
If you don't do that you have effectivly coupled the using code with a specific implementation. There is really no need for any interfaces at all then.
Update
Which repository is used if I inject like
CategoryService(ICategoryRepository repository)
?
The repository that you registered in your inversion of control container. My point is that you should not register both implementations but just one of them for every repository.
A simple example would be below.
First manage the repository type with your web.config:
<configuration>
<appSettings>
<add key="RepositoryType" value="NHibernate" />
</appSettings>
</configuration>
And then do this when you configure your inversion of control container:
if (ConfigurationManager.AppSettings["RepositoryType"] == "NHibernate"))
{
_autofac.RegisterType<NHCategoryRepository>.As<ICategoryRepository>();
_autofac.RegisterType<NHUserRepository>.As<IUserRepository>();
}
else
{
_autofac.RegisterType<EFCategoryRepository>.As<ICategoryRepository>();
_autofac.RegisterType<EFUserRepository>.As<IUserRepository>();
}
Upvotes: 2
Reputation: 68440
You could use a dependency injector as Ninject and inject parameter trough contructor
Your NinjectModule
public class NinjectModule : NinjectModule
{
public override void Load()
{
this.Bind<ICategoryRepositoryEF>().To<CategoryRepositoryEF>();
this.Bind<ICategoryRepositoryNH >().To<CategoryRepositoryNH>();
this.Bind<ICategoryService >().To<CategoryService>();
}
}
Inject dependencies
var kernel = new StandardKernel(new NinjectModule());
var categoryService = kernel.Get<ICategoryService>();
This is just an example but take into account that dependencies should be injected on the composition root (entry point) of the application.
Upvotes: 1