NInject noob here。对于后面的代码墙感到抱歉,但这里有很多活动部分。
我有一个命名空间,用于定义我想要编程的实现不可知的持久性接口。顶级界面如下所示:
namespace Common.PersistenceStrategy
{
public interface IPersistenceStrategy
{
IPersistenceRepositoryInstructionResult Commit();
IPersistenceRepository<T> repositories<T>() where T : class;
}
}
这个界面的一般EF实现在它自己的命名空间&amp;项目:
namespace Common.PersistenceStrategy.EF
{
public class EFPersistenceStrategy : IPersistenceStrategy
{
protected DbContext _context;
public EFPersistenceStrategy(DbContext context)
{
_context = context;
}
//Other Implementation stuff...
}
项目特定的实现获得了它自己的命名空间&amp;项目。我们的想法是覆盖一些通用/默认的EF行为,并作为当前项目中EF依赖的单点。
namespace MyProject.DAL
{
public class MyProjectPersistenceStrategy : EFPersistenceStrategy
{
public MyProjectPersistenceStrategy() : base(new MyProjectDbContext())
{}
//project specific implementation overrides
}
}
到达那里...... 在使用/使用MyProjectPersistenceStrategy的网站中,控制器继承自这个类:
namespace MyProject.Site.Controllers
{
public abstract class ControllerWithUnitOfWork : Controller
{
[Inject]
public IPersistenceStrategy _persistenceStrategy { get; set; }
//other implementation stuff
}
}
最后,这是将IPersistenceStrategy连接到MyProjectPersistenceStrategy的NInject内核代码:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IPersistenceStrategy>().To<BlackoutPersistenceStrategy>();
}
因此,我收到两条与内核绑定部分相关的错误消息:
Error 3 The type 'Common.PersistenceStrategy.EF.EFPersistenceStrategy' is defined in an assembly that is not referenced. You must add a reference to assembly 'Common.PersistenceStrategy.EF...
Error 6 The type 'MyProject.DAL.MyProjectPersistenceStrategy' cannot be used as type parameter 'TImplementation' in the generic type or method 'Ninject.Syntax.IBindingToSyntax<T1>.To<TImplementation>()'. There is no implicit reference conversion from 'MyProject.DAL.MyProjectPersistenceStrategy' to 'Common.PersistenceStrategy.IPersistenceStrategy'. C:\dev\Blackout\Blackout.Site\App_Start\NinjectWebCommon.cs
MyProject.Site已经引用了MyProject.DAL和Common.Persistence,这很好,也很明智。
如果我从我的web项目中引用Common.Persistence.EF,则两个错误都会消失。但这并不是真正的跑步者,因为依赖注入工作的重点是将EF的依赖性隔离到当前项目中的单个模块。似乎NInject无法在MyProjectPersistenceStrategy和IPersistenceStrategy之间走一段关系链,除非它能看到两者之间的整个类树?有没有直接解决方案,或者我在这里做错了什么?欢呼声。
答案 0 :(得分:0)
这不是Ninject问题。它是构建过程(编译)问题。如果缺少对Common.PersistenceStrategy.EF.EFPersistenceStrategy
的引用,则无法构建Web项目,因为MyProject.DAL.MyProjectPersistenceStrategy
继承自那里定义的类。
注释
在构建应用程序后想象一下bin文件夹。它必须包含Common.PersistenceStrategy.EF.dll
才能运行您的应用程序(实际上它必须包含未在GAC中注册的所有必需的dll)。因此,MsBuild希望您声明对该项目dll的引用,因为他从*.csproj
文件中读取了构建应用程序所需的dll。在我看来,* .csproj中的<ProjectReference Include="..\MyProject\MyProject.csproj">
只是指向MSBuild,它应该首先在引用的构建脚本上运行构建,但不会查找其中的其他引用。实际上,如果查看VS中引用项目的Properties,则该路径指向该项目的bin文件夹。
答案 1 :(得分:0)
通过在.DAL和.Site命名空间之间添加一个新程序集(仅包含一个NInject模块)来解决这个问题。
这个新程序集包含一个可交换的球中的所有持久性实现依赖项,因此.Site命名空间只需要引用它和接口.Site消耗(在本例中为Common.Persistence)。