I'm trying to use Ninject with a WCF service of mine. I'm using Ninject 2.2.1.4 and Ninject.Extensions.Wcf 2.2.0.4. My unit test to ensure Ninject is working properly fails with an ArgumentNullException; Parameter root: null.
Here is my code:
//A couple of classes to setup ninject and its bindings
public class NinjectBindings : NinjectModule
{
public override void Load()
{
Bind<IEmployeeRepository>().To<SqlEmployeeRepository>().InSingletonScope();
}
}
public class Global : NinjectWcfApplication
{
protected override IKernel CreateKernel()
{
IKernel kernel = new StandardKernel(new NinjectBindings());
return kernel;
}
}
//Test method that fails with ArgumentNullException
[TestMethod]
public void Should_Be_Able_To_Get_Employee_Service_From_Ninject()
{
Global globalService = new Global();
var kernel = globalService.Kernel;
EmployeeService employeeService = kernel.Get<EmployeeService>();
Assert.IsNotNull(employeeService);
}
After creating Global you have to initialize it properly by calling Application_Start() and Init() as IIS would do. After this your integration test should run.
But be aware that in reality kernel.Get is not triggered directly as you do in your test. The creation of the service is much more complex.
When using Ninject.Wcf, your Global doesnt get newd as you've done - you tell WCF that the factory for creating Global is ~NinjectWcfHostFactory, which triggers the CreateKernel() that's not happening in your context.
The example shows the overriding of the factory (in a propery on the service declaration within the .svc file).
Related
I am writing an ASP.NET MVC code and I try to implement inversion of control via Microsoft Unity.
I follow the document above:
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection
Here is my project structure:
Model
Presentation
Repository
Service
Web
Web can only sees Presentation. Presentation can only sees Service. Here is my Bootstrapper.cs file in Web Layer.
public static class Bootstrapper
{
public static IUnityContainer Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
return container;
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
container.RegisterType<IButcePresenter, ButcePresenter>();
container.RegisterType<IProjeFaaliyetPresenter, ProjeFaaliyetPresenter>();
container.RegisterType<ISektorPresenter, SektorPresenter>();
container.RegisterType<IProjePresenter, ProjePresenter>();
container.RegisterType<IFaaliyetPresenter, FaaliyetPresenter>();
container.RegisterType<IKurumCografyaLokasyonPresenter, KurumCografyaLokasyonPresenter>();
container.RegisterType<IVeriSaglayici, VeriSaglayici>();
return container;
}
}
I call the Bootstrapper class inside Global.asax.cs as such:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
Bootstrapper.Initialise();
}
}
Here is my main controller:
public class ErpController : Controller
{
//
private readonly IButcePresenter _butcePresenter;
private readonly IProjeFaaliyetPresenter _iProjeFaaliyetPresenter;
private readonly ISektorPresenter _sektorPresenter;
private readonly IProjePresenter _projePresenter;
private readonly IFaaliyetPresenter _faaliyetPresenter;
private readonly IKurumCografyaLokasyonPresenter _kurumCografyaPresenter;
private readonly IVeriSaglayici _veriSaglayici;
private readonly CevirmeIslemleri _cevirmeIslem;
public ErpController(IButcePresenter butcePresenter, IProjeFaaliyetPresenter projeFaaliyetPresenter,
ISektorPresenter sektorPresenter, IProjePresenter projePresenter, IFaaliyetPresenter faaliyetPresenter, IKurumCografyaLokasyonPresenter kurumCografyaPresenter, IVeriSaglayici veriSaglayici)
{
this._butcePresenter = butcePresenter;
this._iProjeFaaliyetPresenter = projeFaaliyetPresenter;
this._sektorPresenter = sektorPresenter;
this._projePresenter = projePresenter;
this._faaliyetPresenter = faaliyetPresenter;
this._kurumCografyaPresenter = kurumCografyaPresenter;
this._veriSaglayici = veriSaglayici;
this._cevirmeIslem = new CevirmeIslemleri();
}
}
Here is my IButcePresenter. It is defined at the Presentation layer.
public class ButcePresenter : IButcePresenter
{
private readonly IButceServis _butceServis;
private readonly IYetkiServis _yetkiServis;
private readonly IProjeFaaliyetServis _projeFaaliyetServis;
private readonly Cevirme _cevir = null;
private readonly KontrolIslemleri _kontrolIk = null;
public ButcePresenter(IButceServis butceServis, IYetkiServis yetkiServis, IProjeFaaliyetServis projeFaaliyetServis)
{
this._butceServis = butceServis;
this._yetkiServis = yetkiServis;
this._projeFaaliyetServis = projeFaaliyetServis;
this._cevir = new Cevirme();
this._kontrolIk = new KontrolIslemleri();
}
public ButcePresenter()
{
//TODO: Fools man injection
this._butceServis = new ButceServis();
this._yetkiServis = new YetkiServis();
this._projeFaaliyetServis = new ProjeFaaliyetServis();
this._cevir = new Cevirme();
this._kontrolIk = new KontrolIslemleri();
}
}
I can not define IButceServis 's concrete defition in Unity, because, IButceServis and its concrete implementation ButceServis is at the Service layer. Web layer can not see Service layer. I am getting
The current type, DKMPPIB.Presentation.Soyut.IButcePresenter, is an
interface and cannot be constructed. Are you missing a type mapping?
How can I solve the issue? Could you please any clue? Thanks in advance.
Investigations:
I have investigate these questions and they do not help:
The current type is an interface and cannot be constructed. Are you missing a type mapping?
It asks me a create controller factory. So I did. It does not work.
Exception is: InvalidOperationException - The current type, is an interface and cannot be constructed. Are you missing a type mapping?
It misuse the DI concept, so it does not fit my case.
The current type, is an interface and cannot be constructed. Are you missing a type mapping?
He forgets registering the concrete class.
I have found a solution. I cannot initialize the classes inside the class library independently. When the web layer sees all layers, say Model,Presentation,Repository and Service and when all interfaces has been instantiated in web layer, it works. Main thing that we should understand here is interfaces inside the class libraries cannot be initialized inside class library.
I have built a API service using ASP.NET Core. Just like any other API, this one has to retrieve some data from database, apply some business logic and then send data back to the client.
To start with, I have EmployeeDataContext class that is scaffolded using Entity Framework.Core. This class is derived from Microsoft.EntityFrameworkCore.DbContext as shown below.
public partial class EmployeeDataContext : DataContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
......
}
}
This data context class is used in a data provider class as follows.
public class EmployeeDataProvider : IEmployeeDataProvider, IDisposable
{
private EmployeeDataContext dataContext;
public EmployeeDataProvider(EmployeeDataContext context)
{
this.dataContext = context;
}
// Various CRUD methods
// Dispose
public void Dispose()
{
if ( this.dataContext != null )
{
this.dataContext.Dispose();
}
}
}
The service layer holds a reference to data provider as follows.
public class EmployeeService : IEmployeeService
{
private IEmployeeDataProvider dataProvider;
public EmployeeService(IEmployeeDataProvider dataProvider)
{
DataProvider = dataProvider;
}
// Add/Delete/Update Employee related calls
}
All the dependencies are injected in Startup class as follows.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IEmployeeDataProvider, EmployeeDataProvider>();
services.AddScoped<IEmployeeService, EmployeeService>();
}
}
According to Microsoft doc
The container will call Dispose for IDisposable types it creates.
This mean that EmployeeDataProvider.Dispose() method will be called by container at the end of request lifecycle.
The question I have is about how to implement IDisposable for EmployeeDataProvider class. The link provides best practices for implementing IDisposable for various scenarios which may require you to implement Disposable(bool) also. However, for this scenario, I am not sure if
all that is needed and my current (simple) implementation of Dispose is good enough because (since there is no call via finalizer is involved here). Is my understanding and IDisposable look correct for this situation?
Implementing IDisposable is trivial in the case where your class is sealed:
public sealed class Foo : IDisposable {
private readonly FileStream stream;
public Foo() {
this.stream = new FileStream( ... );
}
public void Dispose() {
this.stream.Dispose();
}
}
You only need the protected virtual void Dispose(Boolean disposing) method, and the recommended implementation of IDisposable if your class will be subclassed.
This is described in the documentation for FxCop rule CA1063 "Implement IDisposable correctly": https://msdn.microsoft.com/en-us/library/ms244737.aspx
Dispose() is not public, sealed, or named Dispose.
Dispose(bool) is not protected, virtual, or unsealed.
In unsealed types, Dispose() must call Dispose(true).
For unsealed types, the Finalize implementation does not call either or both Dispose(bool) or the case class finalizer.
[...]
How to Fix Violations
[...]
Ensure that $className is declared as public and sealed.
Another tip: if your fields are only ever assigned in the type initializer or in the constructor - and should never be assigned a null value - then you should use the readonly modifier (or use read-only auto-properties - which have a readonly backing field) and that way you don't need to do a null-check in your Dispose method.
Note that Dispose() methods are generally idempotent:
https://msdn.microsoft.com/en-us/library/fs2xkftw.aspx
To help ensure that resources are always cleaned up appropriately, a Dispose method should be callable multiple times without throwing an exception.
Historically there were a few classes in .NET 1.x and 2.x that did throw ObjectDisposesException if they were Disposed twice, but I haven't personally observed non-idempotent behaviour since upgrading to .NET 4.x - though it's possible that some poorly-written third-party libraries and components might implement it incorrectly, however.
Recently I have worked with asp.net mvc and I have seen in sample project is using Database Factory class. How can you explain for me why use it ?
IDatabaseFactory class
public interface IDatabaseFactory : IDisposable
{
EFMVCDataContex Get();
}
DatabaseFactory class
public class DatabaseFactory : Disposable, IDatabaseFactory
{
private EFMVCDataContex dataContext;
public EFMVCDataContex Get()
{
return dataContext ?? (dataContext = new EFMVCDataContex());
}
protected override void DisposeCore()
{
if (dataContext != null)
dataContext.Dispose();
}
}
This is an example of an Abstract Factory design pattern. The idea is to create a seam to provide loose coupling between the classes so another type of context could be swapped, either for testing purposes or to extend the application.
Generally speaking, a factory is a way to manage short-lived dependencies, such as database connections. Typically, a framework exposes a way to inject an instance of the factory and then the framework can work with it based on an interface (in this case IDatabaseFactory) as a contract between the framework, and the framework user. The framework will have code that looks something like this:
public interface ISomeService
{
void DoSomething();
}
public class SomeService()
{
private readonly IDatabaseFactory factory;
// The factory is injected through the constructor
public SomeService(IDatabaseFactory factory)
{
this.factory = factory;
}
public void DoSomething()
{
using (EFMVCDataContex context = this.factory.Get())
{
// Run a LINQ query here using the context
} // This bracket disposes the context
}
}
The service can then be instantiated for a much longer lifetime than the context that is created by the factory. What's more is that the context is always properly disposed in this scenario.
Now, the main benefit from doing this is that you can swap the DatabaseFactory with an alternate implementation (commonly referred to as the Liskov Substitution Principle):
public class MyDatabaseFactory : Disposable, IDatabaseFactory
{
private EFMVCDataContex dataContext;
public EFMVCDataContex Get()
{
return dataContext ?? (dataContext = new AlternateDataContext());
}
protected override void DisposeCore()
{
if (dataContext != null)
dataContext.Dispose();
}
}
Assuming that AlternateDataContext inherits (or implements) EFMVCDataContex, MyDatabaseFactory can be swapped apples-for-apples with DatabaseFactory without making any changes to SomeService.
MyDatabaseFactory could be coded with a connection string in the constructor, giving you a way to connect to alternate databases, for example.
Of course, another great benefit of doing this is to create a mock implementation of IDatabaseFactory that can be used to test the DoSomething method. In a unit test, SomeService (the class under test) should be the only real class being used, IDatabaseFactory should be a mock (which could either be done by hand coding a class, or using a mocking framework).
I am familiar with the fact, that i should not use dependency injection in unit tests, so i can unit test each layer independently.
Still, I want to create integration tests for my controllers. Therefore I need to inject my repositories into the Controllers from a unit test.
I a following a generic approach using a T4 script, that creates a test class for each controller, containing a test method for each ActionResult. This test method should simply call the method to make sure no exceptions are thrown to the surface.
Because of using this T4 script, I cannot manually feed the repositories into the controllers. I need to make use of dependency injection.
Based on my former experience, this should work, but i keep getting the error:
Unable to get default constructor for class <<UnitTest>>
My generated classes look like this at the moment:
[TestClass]
public class TestControllersHomeController
{
private EL.NET.Web.Controllers.HomeController c;
//setup
public TestControllersHomeController(Project.Controllers.HomeController c)
{
this.c = c;
}
[ClassInitialize]
public void ClassInitialize()
{
var kernel = NinjectWebCommon.CreatePublicKernel();
kernel.Bind<TestControllersHomeController>().ToSelf();
kernel.Bind<Project.Controllers.HomeController>().ToSelf();
}
[TestMethod]
public void TestIndex()
{
var result = c.Index();
Assert.IsNotNull(result);
}
Edit:
I already found out, that the repositories can be loaded with help of the GetService() method of IKernel. But for the Membership provider, this doesn't work.
Again, I do not want to mock the provider, I want to perform an integration test so I know if my Controller methods throw any exceptions.
The unit test must have a default constructor:
[TestClass]
public class TestControllersHomeController
{
private HomeController _sut;
[TestInitialize]
public void MyTestInitialize()
{
var kernel = NinjectWebCommon.CreatePublicKernel();
_sut = kernel.Resolve<HomeController>();
}
[TestMethod]
public void TestIndex()
{
var result = _sut.Index();
Assert.IsNotNull(result);
}
}
Preliminaries
I'm using Ninject.MVC3 2.2.2.0 Nuget Package for injecting into my controller an implementation of a IDomain Interface that separates my Business Logic (BL) using an Factory approach.
I'm registering my Ninject Modules in the preconfigured NinjectMVC3.cs using:
private static void RegisterServices(IKernel kernel)
{
var modules = new INinjectModule[]
{
new DomainBLModule(),
new ADOModule()
};
kernel.Load(modules);
}
I'm trying to avoid the fatal curse of the diabolic Service Locator anti-pattern.
The Domain Class uses a DBContext that i'm trying to inject an interface implementation too, via an IDBContext, with the following scenario:
IDomainBLFactory:
public interface IDomainBLFactory
{
DomainBL CreateNew();
}
DomainBLFactory:
public class DomainBLFactory : IDomainBLFactory
{
public DomainBL CreateNew()
{
return new DomainBL();
}
}
In the controller's namespace:
public class DomainBLModule : NinjectModule
{
public override void Load()
{
Bind<IDomainBLFactory>().To<DomainBLFactory>().InRequestScope();
}
}
At this point i can inject the IDomainBLFactory implementation into my controller using Ninject Constructor Injection without any problem:
public class MyController : Controller
{
private readonly IDomainBLFactory DomainBLFactory;
// Default Injected Constructor
public MyController(IDomainBLFactory DomainBLFactory)
{
this.DomainBLFactory = DomainBLFactory;
}
... (use the Domain for performing tasks/commands with the Database Context)
}
Now my central problem.
In the DomainBL implementation, i will inject the dependency to a particular DBContext, in this case ADO DBContext from Entity Framework, again, using a IDBContextFactory:
IDbDataContextFactory
public interface IDbDataContextFactory
{
myADOEntities CreateNew();
}
DbDataContextFactory
public class DbDataContextFactory : IDbDataContextFactory
{
public myADOEntities CreateNew()
{
return new myADOEntities ();
}
}
ADOModule
public class ADOModule : NinjectModule
{
public override void Load()
{
Bind<IDbDataContextFactory>().To<DbDataContextFactory>().InRequestScope();
}
}
Now in the DomainBL implementation I faced the problem of injecting the necessary interface for the DBContext Object Factory:
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
**** OPS, i tried to understand about 10+ Stackoverflow articles ***
...
}
What have I tried?
To Use the constructor Injection. But I don't know what to inject in the call for the Factory CreateNew() in the IDBContextFactory. For clear:
public class DomainBLFactory: IDomainBLFactory
{
// Here the constructor requires one argument for passing the factory impl.
public DomainBL CreateNew()
{
return new DomainBL(?????) // I need a IDBContextFactory impl to resolve.
//It's not like in the MVC Controller where injection takes place internally
//for the controller constructor. I'm outside a controller
}
}
In this Useful Post, our unique true friend Remo Gloor describes in a comment a possible solution for me, citing: "Create an interface that has a CreateSomething method that takes everything you need to create the instance and have it return the instance. Then in your configuration you implement this interface and add an IResolutionRoot to its constructor and use this instace to Get the required object."
Questions: How do I implement this in a proper way using Ninject.MVC3 and my modest Domain Class approach? How do I Resolve the IResolutionRoot without be punished for relaying in the Service Locator anti-pattern?
To Use the property injection for an IDBContexFactory. In the course of learning and reading all the contradictory points of view plus the theoretical explanations about it, I can deduce it's not a proper way of doing the injection for my DBContexFactory class code. Nevermind. It doesn't work anyway.
public class DomainBL
{
[Inject]
public IDbDataContextFactory contextFactory
{
get;
set;
}
//Doesn't works, contextFactory is null with or without parameterless constructor
.... (methods that uses contextFactory.CreateNew()....
}
Question: What am I missing? Even if this approach is wrong the property is not injecting.
Be cursed. Use a DependencyResolver and live with the stigmata. This works and I will remain in this approach until a proper solution appears for me. And this is really frustrating because the lack of knowledge in my last 10 days effort trying to understand and do things right.
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
this.contextFactory = DependencyResolver.Current.GetService<IDbDataContextFactory>();
//So sweet, it works.. but i'm a sinner.
}
Question: Is there a big mistake in my understanding of the Factory Approach for the injection of interfaced implementations and using a Domain Driven Approach for taking apart the Business Logic? In the case I'm wrong, what stack of patterns should I implement with confidence?
I saw before a really big quantity of articles and blogs that does not ask this important question in a open a clear way.
Remo Gloor introduces the Ninject.Extensions.Factory for the Ninject 3.0.0 RC in www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction.
Question: Will this extension work coupled with Ninject.MVC3 for general porpouse?. In such case it should be my hope for the near future.
Thank you all in advance for your guidance and remember we appreciate your kind help. I think a lot of people will find this scenario useful too.
I don't really get the purpose of your factories. Normally, you have exactly one ObjectContext instance for one request. This means you don't need the factory and can simply bind myADOEntities in Request scope and inject it into your DomainBL without adding the factories:
Bind<myADOEntities>().ToSelf().InRequestScope();
Bind<DomainBL>().ToSelf().InRequestScope();
And Yes the factory and mvc extrensions work together.
Here's an implementation of a generic IFactory to solve the problem without resorting to the ServiceLocator anti-pattern.
First you define a nice generic factory interface
public interface IFactory<T>
{
T CreateNew();
}
And define the implementation which uses ninject kernel to create the objects requested
class NinjectFactory<T> : IFactory<T>
{
private IKernel Kernel;
public NinjectFactory( IKernel Kernel )
{
this.Kernel = Kernel;
}
public T CreateNew()
{
return Kernel.Get<T>();
}
}
Binding to your factory using the following
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<myADOEntities>().ToSelf();
kernel.Bind<DomainBL>().ToSelf();
kernel.Bind(typeof(IFactory<>)).To(typeof(NinjectFactory<>));
}
You can now do the following in your controller.
public class MyController : Controller
{
private readonly IFactory<DomainBL> DomainBLFactory;
public MyController( IFactory<DomainBL> DomainBLFactory )
{
this.DomainBLFactory = DomainBLFactory;
}
// ... (use the Domain for performing tasks/commands with the Database Context)
}
And in your DomainBL
public class DomainBL
{
IFactory<myADOEntities> EntitiesFactory;
public DomainBL( IFactory<myADOEntities> EntitiesFactory )
{
this.EntitiesFactory = EntitiesFactory;
}
// ... (use the Entities factory whenever you need to create a Domain Context)
}