AliRıza Adıyahşi
AliRıza Adıyahşi

Reputation: 15866

Inject repositories into service?

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

Answers (2)

jgauffin
jgauffin

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

Claudio Redi
Claudio Redi

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

Related Questions