Castle Windsor没有创建/暴露基类

时间:2016-06-21 09:10:30

标签: c# asp.net-mvc entity-framework castle-windsor asp.net-apicontroller

我在Repository项目中有一些使用Entity Framework DbContext Typed基类的Repository类。

基类

public class RepositoryBase<TC> : IDisposable
    where TC : DbContext, new()
{

    public virtual T Get<T>(...) where T : class
    {
        ...
    }

    // ... additional code
}

员工回购接口

namespace Insight.Repository.Interfaces
{
    public interface IEmployeeRepository
    {
        Result CreateEmployee(Employee employee);
        // ... additional code
    }
}

员工回购

namespace Insight.Repository.Repositories
{
    public class EmployeeRepository : RepositoryBase<InsightContext>, IEmployeeRepository
    {
        public Result CreateEmployee(Employee employee)
        {
            return Save(employee);
        }
    }
    // ... additional code
}

我使用基于Repository项目中的Interfaces的安装程序将Repo类添加到Asp.Mvc网站内的Windsor容器中。此时我已经查看了容器,我正在获取我的三个存储库。

public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromAssemblyNamed("Insight.Repository")
           .Where(Component.IsInNamespace("Insight.Repository.Repositories"))
            .WithService.DefaultInterfaces()
            .LifestyleTransient());
    }

我已尝试按如下方式注册DbContext但我得到的结果相同。

container.Register(Component.For<DbContext>()
            .ImplementedBy<InsightContext>()
            .LifestyleTransient());

然后,在我的ApiController中,我然后使用Property注入实例化Repo类,但我无法访问任何基类函数。

public class EmployeeController : ApiController
{
    public IEmployeeRepository EmployeeRepo { get; set; }

    [Route("GetEmployee")]
    public void Get()
    {
        var newEmployeeRepo = new EmployeeRepository();
    }
}

EmployeeRepo无权访问基类中的Get()函数,但newEmployeeRepo可以访问。

这是我使用Castle.Windsor的第一个项目,我显然错过了某种注册步骤,但可以解决这个问题。

如果有人能指出我正确的方向,非常感谢。

编辑:使用tym32167提供的Linqpad代码进行测试

void Main()
{
    var container = new WindsorContainer();

    var type = typeof(II);
    container.Register(Classes.FromAssembly(type.Assembly)
       .Where(Component.IsInNamespace(type.Namespace))
        .WithService.AllInterfaces()
        .LifestyleTransient());

    var cls = container.Resolve<II>().Dump();
    cls.GetFirstName().Dump();
    cls.GetLastName().Dump();
}

public interface II
{
    string GetFirstName();
}

public class MyClass : II
{
    public string GetFirstName()
    {
    return "First Name";
    }

    public string GetLastName()
    {
    return "Last Name";
    }
}

代码在这一行中断:

cls.GetLastName().Dump();

这是预期的行为吗?

2 个答案:

答案 0 :(得分:0)

尝试替换

.WithService.DefaultInterfaces()

.WithService.AllInterfaces()

作为样本(刚用linqpad检查)

void Main()
{   
    var container = new WindsorContainer();

    var type = typeof(II);
    container.Register(Classes.FromAssembly(type.Assembly)
           .Where(Component.IsInNamespace(type.Namespace))
            .WithService.AllInterfaces()
            .LifestyleTransient());

    container.Resolve<II>().Dump();
}

public interface II
{
}

public class MyCl : II
{
}

答案 1 :(得分:0)

要访问基类上的方法,您需要有一个基本接口:)

public interface IBaseRepo<T>
{
     T Get(int id);
     // ...
}

public interface IEmployeeRepo : IBaseRepo<Employee>
{
     Employee GetByFirstName(string name);
     // ...
}

注意子接口如何继承基接口。因此,任何实现IEmployeeRepo的类型都保证它也实现IBaseRepo<Employee>,当你注入一个时,你也可以访问基接口上的方法。

您在基类中实现基本仓库的事实,即您的具体员工仓库继承,这只是客户端代码不应该关心的实现细节 - 现在它不会!