NInject noob here. Sorry about the wall of code that follows, but there’s a lot of moving parts here.
I’ve got a namespace that defines the implementation agnostic persistance interfaces I want to program to. The top level interface looks like this:
namespace Common.PersistenceStrategy
{
public interface IPersistenceStrategy
{
IPersistenceRepositoryInstructionResult Commit();
IPersistenceRepository<T> repositories<T>() where T : class;
}
}
The general EF implementation of this interface goes in it’s own namespace & project:
namespace Common.PersistenceStrategy.EF
{
public class EFPersistenceStrategy : IPersistenceStrategy
{
protected DbContext _context;
public EFPersistenceStrategy(DbContext context)
{
_context = context;
}
//Other Implementation stuff...
}
The project-specific implementation gets it’s own namespace & project. The idea is to override some of the generic/default EF behaviour, and act as the single point of EF-dependance in the current project.
namespace MyProject.DAL
{
public class MyProjectPersistenceStrategy : EFPersistenceStrategy
{
public MyProjectPersistenceStrategy() : base(new MyProjectDbContext())
{}
//project specific implementation overrides
}
}
Getting there…
In the website that’s to consume/use the MyProjectPersistenceStrategy, the controllers are inheriting from this class:
namespace MyProject.Site.Controllers
{
public abstract class ControllerWithUnitOfWork : Controller
{
[Inject]
public IPersistenceStrategy _persistenceStrategy { get; set; }
//other implementation stuff
}
}
And finally, here’s the NInject kernel code to wire IPersistenceStrategy to MyProjectPersistenceStrategy:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IPersistenceStrategy>().To<BlackoutPersistenceStrategy>();
}
So, I’m getting two error messages related to the kernel binding portion:
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 has already got references to MyProject.DAL and Common.Persistence, which is fine and sensible.
Both errors go away if I reference Common.Persistence.EF from my web project. That’s not really a runner though, since the whole point of the dependency injection effort was to isolate the dependency on EF to a single module within the current project. It seems that NInject can’t walk the relationship chain between MyProjectPersistenceStrategy and IPersistenceStrategy unless it can see the whole class tree between the two? Is there a direct solution to this, or am I trying to do the wrong thing here? Cheers.
It is not Ninject issue. It is build process (compilation) issue. You cannot build your web project if reference to
Common.PersistenceStrategy.EF.EFPersistenceStrategyis missing, becauseMyProject.DAL.MyProjectPersistenceStrategyinherits from class defined there.Comment
Imagine the bin folder after you build your application. It must contain
Common.PersistenceStrategy.EF.dllto run your application (actually it must contain all required dlls which are not registered in GAC). Because of that, MsBuild wants you to declare the reference to that project dll, because he reads from the*.csprojfile which dlls are needed to build the application. It seems to me, that<ProjectReference Include="..\MyProject\MyProject.csproj">inside the *.csproj just points MSBuild that it should first run build on that referenced build script, but does not looks on another references inside it. In fact if you look on Properties of referenced project in VS, the path points to bin folder of that project.