Need to pass class object to ninject - c#

So I am working on API and using Ninject for DI & IoC. I know how the basic code works using Ninject but in the constructor of one of the classes an object of Logger is being sent. Rather than send it in constructor design item I would like to pass it in NinjectWebCommon.cs file.
public GAMonthlyAPIController() : this(new GAMonthlySQLReader(new NullLogger()))
This is the constructor.
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
This is the entry in NinjectWebCommon.cs I would like to bind it in NinjectWebCommon.cs rather than default value. How would I pass that? I don't even know what to search for, so I could find answers.

The most practical way to apply the dependency injection pattern is to use constructor injection. This means that the classes GaMonthlyAPIController depend on should be passed in through the constructor, rather than hard-coded inside of the controller.
public class GAMonthlyAPIController
{
private readonly IGAMonthlySQLReader gaMonthlySqlReader;
public GAMonthlyAPIController(IGAMonthlySQLReader gaMonthlySqlReader)
{
this.gaMonthlySqlReader = gaMontlySqlReader
?? throw new ArgumentNullException(nameof(gaMontlySqlReader));
}
// implementation of controller...
}
This should be the only constructor for your controller class. The controller itself doesn't know anything about GAMontlySqlReader or any of its dependencies.
The same goes for GAMonthlySQLReader - it will allow any ILogger implementation to be injected through the constructor.
The idea is that it puts the composition root of the application in charge of how the dependencies are composed together, meaning you can easily switch them around later without making any changes to the components that you are composing. So, Ninject would be used inside of your composition root to map types to their abstraction, and then will build object graphs of all of those dependencies composed together.
kernel.Bind<ILogger>().To<MyLoggerClass>();
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
For each of the application services, you would allow Ninject to instantiate them (so it can supply the dependencies) rather than using the new keyword inside of your application (new can be used for DTOs and Models, though).

I think you need to add Ninject.Web.WebApi using nuget to your Web Api project. Then use Ninject for creating ApiControllers:
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
And add the Bind() for GAMonthlyAPIController. No need to create a default constructor for your controller.
Have a look to this post:
http://nodogmablog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/

Related

How to define DbContext scope in WPF application similar to ASP.NET?

I want to use same technology to access my database both from ASP.NET MVC and WPF and decided to use EF Core.
In ASP.NET I can inject DbContext(UnitOfWork, AppBLL etc) into Controller and its lifecycle is scoped to request/response operation. As I understood the scope is created behind the scenes using ASP.NET middleware pipeline.
In WPF however scope must be defined based on the app use case which is completely logical since some times there is need for long operation (for example using DbSet.Local.ToObservableCollection() and DataGrid) and sometimes operation is more trivial (for example update one entity).
I want to achieve somewhat similar behavior to ASP.NET MVC in WPF, basically I want to inject DbContext into ViewModel constructor and then each method to be its own scope thus have different short-lived DbContext each method call.
I use Microsoft.Extensions.DependencyInjection and CommunityToolkit.MVVM for DI and add DbContext using AddDbContext. This makes it scoped but without defining the scopes it is effectively singleton. I do not want to define scope with using(var scope = ...) and GetRequiredService each time I make a db operation since it will pollute my code.
As I said I want it to be sleek like in ASP.NET.
So I tried aspect oriented programming with PostSharp but feels kinda dull to add attributes to each method that uses DbContext also there are concerns about testability.
I tried implementing abstract class which has methods to which lambda with operation is passed and lambda is created inside a using(var scope = ...) expression and thus uses scoped DbContext. At the disposal of the scope DbContext is automatically disposed with it.
These approaches however are still distant from ASP.NET mechanism and
I want DbContext lifecycle to be managed smarter.
If I define DbContext as transient then it is only created on injection into ViewModel and not re-created for methods.
By the way, do I understand correctly that in ASP.NET when DbContext is injected into Controller it is disposed right after the construction, since the scope is finished?
EDIT:
Here is a link to example project Github repository
https://github.com/anguzo/ef-core-in-wpf-example
WpfApp project is example of the problem - you can't update same entity twice since it's already being tracked.
Other WPF projects demonstrate different solutions to this problem I came up with.
The closest to the ASP.NET behavior is using PostSharp custom attribute. It requires attribute to be applied to ViewModel class and modifies each method(excluding "special methods": getters, setters and consturctors).
I am still lost since official Microsoft documentation and other materials on the Internet do not describe proper solution to this problem.
The dependency injection container is an instance class.
With mvc there is a request pipeline that provides the parameters of anything instantiated by it from that container.
The difference between mvc and wpf is that with wpf you don't have that pipeline so you need to provide the container instance somehow whenever you instantiate a class you want anything injected to.
It's covered pretty well here:
https://learn.microsoft.com/en-us/windows/communitytoolkit/mvvm/ioc
You do not want everything to be a singleton and you do not want to resolve the entire object graph as you crank up your application.
As you spotted, that's impractical anyhow because you want some things to be transient.
Passing the DI container around is a nuisance. You might have any number of layers down to your dbcontext.
What is usual is to make the injection container available throughout the app.
In the code there, they've added a property to App to stash that instance in:
public sealed partial class App : Application
{
public App()
{
Services = ConfigureServices();
this.InitializeComponent();
}
/// <summary>
/// Gets the current <see cref="App"/> instance in use
/// </summary>
public new static App Current => (App)Application.Current;
/// <summary>
/// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
/// </summary>
public IServiceProvider Services { get; }
App.Services is your dependency injection container. The magic bag you grab your instances out of.
Where these services are registered they're all singletons there, but your dbcontext should be
services.AddTransient<IMyDbContext, MyDbContext>();
And your repository would take an IMyDbContext in it's constructor which would be supplied out the container.
You need to reference that container exposed by App to resolve an instance:
var repo = App.Current.Services.GetService<IRepository>();
Because it's on App.Current, everywhere in your code will be able to reference it. So long as you have a regular wpf entry point.
Your repository would get an instance of dbcontext via injection and you'd so whatever you're doing with that repository. Once it goes out of scope the repository and dbconnection would be ready for garbage collection so long as they're both Transient.
Transients will be disposed after they go out of scope. Hence if you pass a transient dbcontext down from a mvc controller then it will stay in scope until the response is sent from the controller. It's only going to be torn down after the controller's returned it's result and goes out of scope.
The aspect of the code which I would change is to add an abstracted facade around the di container. You want to be able to moq whatever grabs a class instance out that container if you use it within any classs. If you use app.current in unit testing then you need to instantiate an application object.
What Andy outlines is pretty much what I use, it's commonly referred to as a Service Locator pattern, and has a bit of a reputation as an anti-pattern, but for WPF it is pretty effective if you have some discipline within your team about where and how it is allowed to be used.
I'd recently written a quick snippet on using the ServiceLocator pattern and lazy dependency properties with Autofac which can provide some ideas on how the pattern can be applied:
private readonly IContainerScope _scope;
private ISomeDependency? _someDependency = null;
public ISomeDependecy SomeDependency
{
get => _someDependency ??= _scope.Resolve<ISomeDependency>()
?? throw new ArgumentException("The SomeDependency dependency could not be resolved.");
set => _someDependency = value;
}
public SomeClass(IContainer container)
{
if (container == null) throw new ArgumentNullException(nameof(container));
_scope = container.BeginLifetimeScope();
}
public void Dispose()
{ // TODO: implement proper Dispose pattern.
_scope.Dispose();
}
This gives you a pattern gives you a default lifetime scope for the life of a top-level dependency which could be a MVVM ViewModel, and/or navigation provider, etc. so your dependencies can be managed by Transient, Singleton, or PerLifeTimeScope. (Suited to something like the EF DbContext) So for instance when a form is loaded the DbContext instance can be resolved for the lifetime of that form.
I call the pattern a lazy property pattern as the actual dependency is resolved only if/when it is accessed via the property. The advantage of this is when writing unit tests with classic constructor injection, you need to mock every dependency for every test, where with "lazy" properties you use the Setter for just the dependencies you need. The initialization of the class under test accepts a mocked container that simply throws an exception to fail the test if it's Resolve<T> method is called. (No need to build a functional mock container for tests to resolve mocked dependencies or other such complexity)
The caveat of this pattern, and one suggestion to work with the team on to check is that the _scope reference should only be accessed from the dependency properties, not willy-nilly through the code to resolve dependencies ad-hoc. For instance if a new dependency is needed, declare the property accessor to resolve via the scope rather than just writing a _scope.Resolve<NewDependency>() in the code. While you can still test around such code, you'd need to set up your tests to provide a _scope capable of resolving a Mock, which is honestly messy. Following the property pattern makes testing a lot simpler to provide the expected dependency via the Setter and getting an exception/failure if an unexpected dependency happens to get accessed.
It's not proper-C#-Lazy, though I do use a proper Lazy dependency pattern for injected dependencies, and web projects where the lifetime scope is conveniently managed:
private readonly Lazy<ISomeDependency>? _lazySomeDependency = null;
private ISomeDependency? _someDependency = null;
public ISomeDependency SomeDependency
{
get => _someDependency ??= _lazySomeDependency?.Value
?? throw new ArgumentException("SomeDependency dependency was not provided.");
set => _someDependency = value;
}
public SomeClass(Lazy<ISomeDependency>? someDependency = null)
{
_lazySomeDependency = someDependency;
}
Autofac does support lazy initialization so this pattern means that for normal execution, Autofac provides the properties as Lazy references which will resolve if/when they are accessed. For unit tests, you just initialize with an empty constructor and use the Setters to set the dependencies you expect to actually be used. The above example with 1 dependency doesn't really demonstrate the value of that, but picture a test suite for a class that has 8 or 12 dependencies where a method under test will likely only touch a couple of them.

Dependency injection of multiple instances of same type in ASP.NET Core 2

In ASP.NET Core 2 Web Api, I want to use dependency injection to inject httpClientA instance of HttpClient to ControllerA, and an instance httpClientB of the HttpClient to ControllerB.
The DI registration code would look something like:
HttpClient httpClientA = new HttpClient();
httpClientA.BaseAddress = endPointA;
services.AddSingleton<HttpClient>(httpClientA);
HttpClient httpClientB = new HttpClient();
httpClientB.BaseAddress = endPointB;
services.AddSingleton<HttpClient>(httpClientB);
I know I could subclass HttpClient to make a unique type for each controller, but that doesn't scale very well.
What is a better way?
UPDATE
Specifically regarding HttpClient Microsoft seems to have something in the works
https://github.com/aspnet/HttpClientFactory/blob/dev/samples/HttpClientFactorySample/Program.cs#L32 - thanks to #mountain-traveller (Dylan) for pointing this out.
Note: This answer uses HttpClient and a HttpClientFactory as an example but easily applies to any other kind of thing. For HttpClient in particular, using the new IHttpClientFactory from Microsoft.Extensions.Http is preferred.
The built-in dependency injection container does not support named dependency registrations, and there are no plans to add this at the moment.
One reason for this is that with dependency injection, there is no type-safe way to specify which kind of named instance you would want. You could surely use something like parameter attributes for constructors (or attributes on properties for property injection) but that would be a different kind of complexity that likely wouldn’t be worth it; and it certainly wouldn’t be backed by the type system, which is an important part of how dependency injection works.
In general, named dependencies are a sign that you are not designing your dependencies properly. If you have two different dependencies of the same type, then this should mean that they may be interchangeably used. If that’s not the case and one of them is valid where the other is not, then that’s a sign that you may be violating the Liskov substitution principle.
Furthermore, if you look at those dependency injection containers that do support named dependencies, you will notice that the only way to retrieve those dependencies is not using dependency injection but the service locator pattern instead which is the exact opposite of inversion of control that DI facilitates.
Simple Injector, one of the larger dependency injection containers, explains their absence of named dependencies like this:
Resolving instances by a key is a feature that is deliberately left out of Simple Injector, because it invariably leads to a design where the application tends to have numerous dependencies on the DI container itself. To resolve a keyed instance you will likely need to call directly into the Container instance and this leads to the Service Locator anti-pattern.
This doesn’t mean that resolving instances by a key is never useful. Resolving instances by a key is normally a job for a specific factory rather than the Container. This approach makes the design much cleaner, saves you from having to take numerous dependencies on the DI library and enables many scenarios that the DI container authors simply didn’t consider.
With all that being said, sometimes you really want something like this and having a numerous number of subtypes and separate registrations is simply not feasible. In that case, there are proper ways to approach this though.
There is one particular situation I can think of where ASP.NET Core has something similar to this in its framework code: Named configuration options for the authentication framework. Let me attempt to explain the concept quickly (bear with me):
The authentication stack in ASP.NET Core supports registering multiple authentication providers of the same type, for example you might end up having multiple OpenID Connect providers that your application may use. But although they all share the same technical implementation of the protocol, there needs to be a way for them to work independently and to configure the instances individually.
This is solved by giving each “authentication scheme” a unique name. When you add a scheme, you basically register a new name and tell the registration which handler type it should use. In addition, you configure each scheme using IConfigureNamedOptions<T> which, when you implement it, basically gets passed an unconfigured options object that then gets configured—if the name matches. So for each authentication type T, there will eventually be multiple registrations for IConfigureNamedOptions<T> that may configure an individual options object for a scheme.
At some point, an authentication handler for a specific scheme runs and needs the actual configured options object. For this, it depends on IOptionsFactory<T> whose default implementation gives you the ability to create a concrete options object that then gets configured by all those IConfigureNamedOptions<T> handlers.
And that exact logic of the options factory is what you can utilize to achieve a kind of “named dependency”. Translated into your particular example, that could for example look like this:
// container type to hold the client and give it a name
public class NamedHttpClient
{
public string Name { get; private set; }
public HttpClient Client { get; private set; }
public NamedHttpClient (string name, HttpClient client)
{
Name = name;
Client = client;
}
}
// factory to retrieve the named clients
public class HttpClientFactory
{
private readonly IDictionary<string, HttpClient> _clients;
public HttpClientFactory(IEnumerable<NamedHttpClient> clients)
{
_clients = clients.ToDictionary(n => n.Name, n => n.Client);
}
public HttpClient GetClient(string name)
{
if (_clients.TryGet(name, out var client))
return client;
// handle error
throw new ArgumentException(nameof(name));
}
}
// register those named clients
services.AddSingleton<NamedHttpClient>(new NamedHttpClient("A", httpClientA));
services.AddSingleton<NamedHttpClient>(new NamedHttpClient("B", httpClientB));
You would then inject the HttpClientFactory somewhere and use its GetClient method to retrieve a named client.
Obviously, if you think about this implementation and about what I wrote earlier, then this will look very similar to a service locator pattern. And in a way, it really is one in this case, albeit built on top of the existing dependency injection container. Does this make it better? Probably not, but it’s a way to implement your requirement with the existing container, so that’s what counts. For full defense btw., in the authentication options case above, the options factory is a real factory, so it constructs actual objects and doesn’t use existing pre-registered instances, so it’s technically not a service location pattern there.
Obviously, the other alternative is to completely ignore what I wrote above and use a different dependency injection container with ASP.NET Core. For example, Autofac supports named dependencies and it can easily replace the default container for ASP.NET Core.
Another option is to
use an additional generic type parameter on the interface or a new interface implementing the non generic interface,
implement an adapter/interceptor class to add the marker type and then
use the generic type as “name”
I’ve written an article with more details: Dependency Injection in .NET: A way to work around missing named registrations
Use named registrations
This is exactly what named registrations are for.
Register like this:
container.RegisterInstance<HttpClient>(new HttpClient(), "ClientA");
container.RegisterInstance<HttpClient>(new HttpClient(), "ClientB");
And retrieve this way:
var clientA = container.Resolve<HttpClient>("ClientA");
var clientB = container.Resolve<HttpClient>("ClientB");
If you want ClientA or ClientB automatically injected into another registered type, see this question. Example:
container.RegisterType<ControllerA, ControllerA>(
new InjectionConstructor( // Explicitly specify a constructor
new ResolvedParameter<HttpClient>("ClientA") // Resolve parameter of type HttpClient using name "ClientA"
)
);
container.RegisterType<ControllerB, ControllerB>(
new InjectionConstructor( // Explicitly specify a constructor
new ResolvedParameter<HttpClient>("ClientB") // Resolve parameter of type HttpClient using name "ClientB"
)
);
Use a factory
If your IoC container lacks any ability to handle named registrations, you could inject a factory and let the controller decide how to get the instance. Here is a really simple example:
class HttpClientFactory : IHttpClientFactory
{
private readonly Dictionary<string, HttpClient> _clients;
public void Register(string name, HttpClient client)
{
_clients[name] = client;
}
public HttpClient Resolve(string name)
{
return _clients[name];
}
}
And in your controllers:
class ControllerA
{
private readonly HttpClient _httpClient;
public ControllerA(IHttpClientFactory factory)
{
_httpClient = factory.Resolve("ClientA");
}
}
And in your composition root:
var factory = new HttpClientFactory();
factory.Register("ClientA", new HttpClient());
factory.Register("ClientB", new HttpClient());
container.AddSingleton<IHttpClientFactory>(factory);
Really the consumer of the service should not care where about the implementation of the instance it is using. In your case I see no reason to manually register many different instances of HttpClient. You could register the type once and any consuming instance that needs an instance will get it's own instance of HttpClient. You can do that with AddTransient.
The AddTransient method is used to map abstract types to concrete services that are instantiated separately for every object that requires it
services.AddTransient<HttpClient, HttpClient>();

Dependency Injection With Unity Using Constructors With Runtime Parameters

I have the basics down of dependency injection but where I'm struggling is trying to put it together properly in an MVC API C# application using Unity. The issue I have is that I will have a controller that has a method, and in that method it will have say two objects. One of these objects will have a dependency on a data access layer and the other doesn't. I'm not quite sure on exactly how to set this up.
Lets say I have a controller with the following method that gets users from a search object. It also uses a SearchParameters object to perform the search. If you search with no name you get all results, or if you put a name you get any users with that name.
public Users[] GetUsers(string name) {
Company.SearchParameters searchParams = new Company.SearchParameters(name);
Company.UserSearchService searchService = new Company.UserSearchService(searchParams);
return searchService.Search();
}
This is of course a super simplified version but in this case UserSearchService in the Search method is doing an explicit database call. So I know that is a dependency I'd have to give it. SearchParameters really is just a class that holds data.
Here is where I'm not sure on exactly what to do next. The Controller itself doesn't have a dependency but since UserSearchService does I'm not sure how using unity I properly set that up and take into account runtime values for the constructor. I'm also not sure if SearchParameters is supposed to be considered a dependency or not.
Additionally SearchParameters and UserSearchService do not have any sort of backing interface if that matters and there are other methods on this controller that interact with other classes that have a similar need of a data access layer dependency such as perhaps Company.UserAccount.
The search parameters shouldn't be part of constructor; it should be part of the "Search" method. The SearchParameter object should not even be known outside of the UserSearchService class (Encapsulation). There should be some refactoring as neleus suggested. At the very least, to get things going, it should be refactored to something similar this:
public Users[] GetUsers(string name) {
// Or however you end up with your UserSearchService object.
// Ideally as an interface and an injected dependency...
Company.UserSearchService searchService = new Company.UserSearchService();
return searchService.Search(name);
}
Company.UserSearchService:
public Users[] Search(string name) {
// A factory would be a better option. This should also be an interface.
Company.SearchParameters searchParams = new Company.SearchParameters(name);
// Your logic here
}
I see here two tasks. The first is a refactoring where static dependencies have to be replaced with interfaces. The second task is to register your stuff in IoC container.
For the first task a minimum you need is to replace all references to Database in your UserSearchService with IDatabase interface (so that it can also be mocked) and allow it to be passed to constructor (constructor injection). To be able to provide an instance of IDatabase to the service you have to create the same dependency for the controller (again constructor injection). Then register the IDatabase implementation as shown in this post.
Update
I agree that dependency has to be removed from the controller. As you #Topojijo have suggested a factory for the UserSearchService can be used in this case. Guessing you have several cervices you need to make a factory for each and there may be an overhead if their count is large. In such case it's better to resolve the service directly from Unity container and move the searchParams to Search method:
public Users[] GetUsers(string name) {
Company.SearchParameters searchParams = new Company.SearchParameters(name);
Company.UserSearchService searchService = container.Resolve<Company.UserSearchService>();
return searchService.Search(searchParams);
}

Confusion about DI, IoC and service locators

I have read various articles about IoC, DIP, DI and Service Locators but I'm a bit confused which is which because some articles have too vague examples and some other articles have just some specific examples without mentioning other cases.
Could you please clear this up for me, looking at the examples below and shortly explaining which examples match which pattern?
manually passing interface to constructor:
class Consumer
{
public Consumer(IStore store){...}
}
...
Consumer c = new Consumer(new ConcreteStore());
the same as the first example but using some 3rd party library (Unity, Windsor, Ninject)
the same as the first example but using BaseStore class instead of IStore interface
passing dependency to some other method, not to constructor:
class Consumer
{
public BySomething(IStore store){...}
}
...
Consumer c = new Consumer();
c.BySomething(new ConcreteStore());
passing dependencies masked inside of some other interface (bonus for this solution - when some other things are invented in the "world" and Consumer wishes to use them, we don't have to change constructor argument but just update IWorld; and we can completely replace entire World with something else when testing):
interface IWorld
{
IDictionary<string,IStore> Stores { get; set; }
IDictionary<string,ICityMap> Maps { get; set; }
...
}
class Consumer
{
public Consumer(IWorld world){...}
public BySomething(string store, string city){...}
}
...
IWorld myWorld = new HeavenlyWorld();
... // adding stores, maps and whatnot
Consumer c = new Consumer(myWorld);
a sub-question: in this case, is IWorld a service locator or not exactly?
passing a call-back function or delegate (.NET Action in this case):
c.BySomething(store, city, new Action(() => {...} ));
I added this case because the article Inversion of Control states that every callback is IoC. Is it true?
Everything you listed is a form of Dependency Injection.
"Poor Man's" DI
DI using an IoC container
"Poor Man's" DI again. DI works whether you are using an interface or an abstract class.
Method Injection
I'm not sure what you're asking here. It sounds like you want to change the instance of IWorld at runtime, which might be a case for Property Injection instead of Constructor Injection. Properties are oft used for optional dependencies or those that can change. Whether you then set that dependency at run-time with a Service Locator or other means is up to you. Another thing to consider is that IWorld might just depend on context, in which case you could do a context-depdendent constructor injection, the details of which are beyond the scope of this question.
Not related to DI
Every time you pass a dependency as a constructor/method argument, that's Dependecy Injection. It can be manual, like in most of your examples, or automatic using a DI Container aka IoC Container.
Using a container means the objects using deps are constructed by the container. You could ask the container directly for that service and in that case, there's a static property or method ( think DependecyResolver in asp.net mvc) that exposes that service. In that case you're using the Service Locator pattern. IWork in your example is not a locator, it's just a dependency.
To continue with the dependency resolver example, you register all relevant types into a container, the container is build then registered as the dependency resolver. The asp.net mvc framwork then uses the resolver (the Service Locator - SL) to instantiate controllers, views and all the deps these require.
To use the SL pattern is ok as part of a framework, but it's not ok if you're using it in your app to instantiate objects, because it couples the code to the locator. Sometimes is the only solution but 99% you is just an anti-pattern.

How to access Ninject.Kernel without using Service Locator pattern

I have read dozens of posts regarding this topic, without finding a clear guideline of how to access the Ninject.Kernel without using the Service Locator pattern.
I currently have the following in the classes that need to use CustomerBusiness (which is my service) and it works fine, but I am well aware that it is not the recommended way of doing it.
private CustomerBusiness _customerBusiness;
private ICustomerRepository CustomerRepository
{
get { return NinjectWebCommon.Kernel.Get<IAccountRepository>(); }
}
private CustomerBusiness CustomerBusiness
{
get
{
if (_customerBusiness == null)
{
_customerBusiness = new CustomerBusiness(AccountRepository);
}
return _customerBusiness;
}
}
public Customer GetCustomer(int id)
{
return CustomerBusiness.GetCustomer(id);
}
This is the Kernel property accessed in the code above:
public static IKernel Kernel
{
get
{
return CreateKernel();
}
}
I've read many suggestions about using a factory for this, but none of them explain how to use this factory. I would really appreciate if anyone could show me the "CustomerFactory" or any other recommended approach including how to use it.
Update
I am using ASP.NET Web Forms and need to access CustomerBusiness from CodeBehind.
Solution
The final solution that I found to be working, was the answer with the most votes found at this post:
How can I implement Ninject or DI on asp.net Web Forms?
It looks like this (Note inheritance from PageBase, which is part of Ninject.Web - that is the key!):
public partial class Edit : PageBase
{
[Inject]
public ICustomerBusiness CustomerBusiness { get; set; }
...
The accepted answer below indirectly lead me to find this solution.
Since you're using NinjectWebCommon, I assume you have a web application of some sort. You really should only access the Ninject kernel in one place - at the composition root. It is the place where you are building the object graph and the only place you should ever need an access to the IoC container. To actually get the dependencies you need, you typically employ constructor injection.
In case of MVC web applications, for example, you have a controller factory using the Ninject kernel and that's the only place which references it.
To expand on your particular situation, your class would accept ICustomerBusiness in its constructor, declaring that it needs an instance of ICustomerBusiness as its dependency:
class CustomerBusinessConsumer : ICustomerBusinessConsumer
{
private readonly ICustomerBusiness customerBusiness;
public CustomerBusinessConsumer(ICustomerBusiness customerBusiness)
{
this.customerBusiness = customerBusiness;
}
...
}
Now, whichever class uses ICustomerBusinessConsumer as its dependency, would follow the same pattern (accepting an instance of ICustomerBusinessConsumer as its constructor parameter). You basically never construct your dependencies manually using new (specific exceptions aside).
Then, you just have to make sure your classes get their dependencies and it's this composition root where you do this. What exactly is composition root depends on the type of an application you are writing (console application, WPF application, web service, MVC web application...)
EDIT: To get myself familiar with the situation in the ASP.NET WebForms realm
I had to look up the details since I've never used it. Unfortunately, WebForms require you to have a parameterless constructor at each of your Page classes, so you can't use constructor injection all the way from the top of the object graph down to the bottom.
However, after consulting Mark Seeman's chapter on composing objects in WebForms, I can rephrase how to deal with this framework's inefficiency, while still acting in line with good DI practices:
Have a class responsible for resolving the dependencies, using the Ninject's kernel you have set up. This may be a very thin wrapper around the kernel. Let's call it DependencyContainer.
Create your container and save it in the application context, so that it's ready when you need it
protected void Application_Start(object sender, EventArgs e)
{
this.Application["container"] = new DependencyContainer();
}
Let's suppose your page class (let's call it HomePage) has a dependency on ICustomerBusinessConsumer. Then DependencyContainer has to allow us to retrieve an instance of ICustomerBusinessConsumer:
public ICustomerBusinessConsumer ResolveCustomerBusinessConsumer()
{
return Kernel.Get<ICustomerBusinessConsumer>();
}
Than in the MainPage class itself, you will resolve its dependencies in the default constructor:
public MainPage()
{
var container = (DependencyContainer) HttpContext.Current.Application["container"];
this.customerBusinessConsumer = container.ResolveCustomerBusinessConsumer();
}
Few notes:
having the dependency container available in the HttpContext must not be tempting to consider it a service locator. In fact, the best practice here (at least from the standpoint of being true to DI) is to have some kind of "implementor" classes to which you will relay the functionality of your page classes.
For example, each action handled by MainPage will be only relayed to its implementor class. This implementor class will be a dependency of MainPage and, as all other dependencies, will be resolved using the container.
The important part is that these implementor classes should be in assemblies not referencing the ASP.NET assemblies and thus without a chance to access the HttpContext
having to write so much code to achieve this is certainly not ideal, but it is only a consequence of the framework's limitation. In ASP.NET MVC applications, for example, this is dealt with in a much better way. There you have single point where you can compose the object graphs and you don't have to resolve them in each top-level class as you have to in WebForms.
the good thing is that while you have to write some plumbing code in the page class constructors, from there down the object graph you can employ constructor injection
Constructor injection is the preferred method for DI with ninject, however it also supports property injection. Take a read of the ninject page around injection patterns here https://github.com/ninject/ninject/wiki/Injection-Patterns.
Both of these are injection patterns unlike service location which is request based, not really injection at all.
The flipside of injection is that you need to control construction. When using MVC all of the wiring to do this is built into the MVC ninject package on nuget

Categories

Resources