Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Castle Windsor register an interface

I have an assembly called 'MyApp.DAL' and it contains and interface IRepository. I also have another assembly 'MyApp.Repository' where I have slightly more complex repositories deriving from IRepository.

I also have the service layer 'MyApp.Service' where some services reference the complex repositories from 'MyApp.Respository' and also the simple interface IRepository from 'MyApp.DAL'.

This is the interface:

public interface IRepository<T> where T : class
{
    void Add(T entity);
    void Update(T entity);
    void Delete(T entity);
    T GetById(long Id);
}

And this is the implementation:

public abstract class Repository<T> : IRepository<T> where T : class
{
    private MyContext dataContext;
    private readonly IDbSet<T> dbset;

    protected Repository(IDatabaseFactory databaseFactory)
    {
        DatabaseFactory = databaseFactory;
        dbset = DataContext.Set<T>();
    }

    protected IDatabaseFactory DatabaseFactory
    {
        get;
        private set;
    }

    protected MyContext DataContext
    {
        get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
    }

    public virtual void Add(T entity)
    {
        dbset.Add(entity);
    }

    public virtual void Update(T entity)
    {
        dbset.Attach(entity);
        dataContext.Entry(entity).State = EntityState.Modified;
    }

    public virtual void Delete(T entity)
    {
        dbset.Remove(entity);
    }


    public virtual T GetById(long id)
    {
        return dbset.Find(id);
    }
}

And this is a service in the 'Service' layer:

public interface ICustomerService : IUpdateableService<Customer>
{
    List<Customer> GetCustomers();
}

public class CustomerService : ICustomerService
{
    private IUnitOfWork unitOfWork;
    private IRepository<Customer> customerRepository;

    public CustomerService(IUnitOfWork unitOfWork, IRepository<Customer> customerRepository)
    {
        this.unitOfWork = unitOfWork;
        this.customerRepository = customerRepository;
    }
    public List<Customer> GetCustomers()
    {
        return customerRepository.GetAll().ToList();
    }

    public CustomerGet(int id)
    {
        return customerRepository.GetById(id);
    }

    public int Save(Customer customer)
    {
        //TODO
    }

    public bool Delete(Customer customer)
    {
        //TODO
    }

I'm using Castle Windsor to register the types as follows:

        container.Register(
                    Component.For(typeof(IRepository<>))
                         .ImplementedBy(typeof(IRepository<>))
                         .LifeStyle.PerWebRequest,

                    Classes.FromAssemblyNamed("MyApp.Repository")
                        .Where(type => type.Name.EndsWith("Repository"))
                        .WithServiceAllInterfaces()
                        .LifestylePerWebRequest());

However, when I run the app, I get the following error:

Type MyApp.DAL.Interfaces.IRepository1[[MyApp.Model.Customer, MyApp.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] is abstract. As such, it is not possible to instansiate it as implementation of service 'MyApp.DAL.Interfaces.IRepository1'. Did you forget to proxy it?

How can I solve this problem?

like image 282
Ivan-Mark Debono Avatar asked Nov 15 '13 08:11

Ivan-Mark Debono


2 Answers

ImplementedBy must be a concrete class and not an interface/abstract class.

If you want to register all implementations of IRepository<> you can write:

container.Register(
    Classes.FromAssemblyNamed("MyApp.Repository")
            .BasedOn(typeof (IRepository<>))
            .WithService.Base()
            .LifestylePerWebRequest());
like image 21
Allrameest Avatar answered Oct 15 '22 10:10

Allrameest


I see that Repository<T> has no abstract members.

If you do not have any derived classes of Repository<T> then it should not be abstract and IoC will be able to create an instance of Repository<Customer> for you.

container.Register(
    Component.For(typeof(IRepository<>))
        .ImplementedBy(typeof(Repository<>))
        .LifestylePerWebRequest());
like image 156
Ilya Palkin Avatar answered Oct 15 '22 08:10

Ilya Palkin