I want to use Ninject in my Windows application and I want to know if there is best practices that I can do; strategies to find a balance between performance and maintenance.
The problem with Windows application and Web application is that in Web application, there is a scope easy to define that is the context but with Windows application, you have no scope that is easy to use form after form.
As example, I have a service that query the database. This service have a constructor and received a UnitOfWork. With Ninject, I can create a property marked as to be injected but if I do that, each time I will create this service, a new connection will be created to the database.
Just for this reason, I must manually create my services to control the number of connection created and no dependency injector can be used.
I have found that you can call the Inject method after created the service for inject dependencies but I'm sure I can use a better strategy.
With Ninject, you can have Ninject scope lifetimes of your injected dependencies to any object you want to provide (not just Singleton, Request, Thread, and Transient scopes).
From the Ninject Documentation Wiki:
You can also easily define you own
scopes using the .InScope(object o)
method.
You'll find some actual detail about how object scoping works in this Ninject Google Groups question & answer.
I finally found what I searching for.
Create a class that inherits from 'Ninject.Activation.Provider(of T)'
Overrrides the function 'CreateInstance'
Bind your interface with that 'Bind(Of [Your interface]).ToProvider([Your provider class])'
And now, you will be able to control each instance created that are associated with the specified interface.
Note that you can pass a type or an instance to the provider parameter of the Bind method. You can with an instance create a provider before binding your interfaces and use this provider in your code when you want to create a new instance.
The provider in conjunction with InScope allows great flexibility for each place where you want to have and instance of an object that can be injected automatically and have a determined scope.
Here is an example:
Public Interface IConnection
End Interface
Public Class Connection
Implements IConnection
End Class
Imports Ninject
Public Class StandardModule
Inherits Ninject.Modules.NinjectModule
Public Property ConnectionProvider As ConnectionProvider
Public Overrides Sub Load()
Bind(Of IConnection).ToProvider(Me.ConnectionProvider)
End Sub
End Class
Public Class ConnectionProvider
Inherits Ninject.Activation.Provider(Of IConnection)
Public Property Connection As IConnection
Protected Overrides Function CreateInstance(ByVal context As Ninject.Activation.IContext) As IConnection
Return Me.Connection
End Function
End Class
Imports Ninject
Module EntryPoint
Sub Main()
Dim provider As New ConnectionProvider
Dim standardModule As New StandardModule
Dim connection As IConnection
Dim kernel As New Ninject.StandardKernel()
standardModule.ConnectionProvider = provider
kernel = New Ninject.StandardKernel(standardModule)
' Here you should use a factory instead of create an instance directly but
' for demonstration, it show how an instance can be propagated to object created
' by NInject.
provider.Connection = New Connection
connection = kernel.Get(Of IConnection)()
End Sub
End Module
This article by Ayende in MSDN Magazine is ostensibly about NHibernate, and mentions the word inject only once (and that only wrt AOP), but the phrasing of your question suggests to me it'll be great food for thought as you consider how to architect your app.
You can also make your frameworks depend on a factory instance, and rely on the factory to perform your connection pooling.
Alternatively, you can use Ninject itself to always use the same object instance for the particular type.
Related
I'm trying to implement a role provider using a separate EF repository class, as an injectable dependency, to access my roles store. My problem is that the role provider is defined in configuration (web.config) and therefore is not instantiated via the Unity DI container. I haven't been able to find a way to either shift the configuration to code or get hold of the role provider after it's built to call container.BuildUP() on it. Any suggestions would be appreciated.
I think that my question's solution is fairly well covered here:
Property injection in custom membership provider using Castle
If I'd searched on MembershipProvider instead of RoleProvider probably would have found it the first time through.
Just to summarize my solution, the link lead me to the Common Service Locator library at codeplex.
It and the Unity adapter for it are included in the Nuget package for Unity 3. So I already had it.
I added one line to the end of the Compose() method of my CompositionRoot class:
var locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
And I can now access the locator/container thru the static ServiceLocator class in the constructor of my RoleProvider:
public IAuthorizationManager Manager {get; set;}
public MyRoleProvider()
{
var locator = ServiceLocator.Current;
Manager = locator.GetInstance<IAuthorizationManager>();
}
(Of course, you need 'using' statements for Microsoft.Practices.ServiceLocation)
I have an ASP.NET MVC application which uses MEF to implement a plugin framework. Plugins are separate DLLs that exist in the application's bin directory. Plugins usually export one or more controllers like this...
<Export(GetType(IController))>
<MYAPP_Interfaces.Attributes.MVCPluginMetadata(
"SomePlugin",
"A Description for the plugin",
"A Readable Name",
{"ScriptsForThePlugin.js"},
{"StylesForThePlugin.css"},
Enumerations.MVCPluginType.DataView,
"DefaultActionName")>
<PartCreationPolicy(CreationPolicy.NonShared)>
Public Class MyPluginController
Inherits System.Web.Mvc.Controller
<Import()>
Private m_objHost As IWebHost
... and so on.
This all works fine, the host app includes all controllers in an ImportMany property, and composes itself upon creation in the usual way. So m_objHost is populated automagically and the controller has access to all the things the host application provides, like logging and information about the user and what they're currently working on and all that.
My question has to do with my models, and any DAL or utility classes that I have in a plugin. These classes usually have need of information from the IWebHost object. However, the host doesn't need to know about these classes, so they are not included in composition. Since they are not composed, if they want an IWebHost reference they each have to compose themselves upon instantiation, like this:
Public Class MyModel
<Import()>
Private m_objHost As IWebHost
<Import()>
Private m_objLog As ILog
Public Sub New()
Compose()
End Sub
...
Private Sub Compose()
Try
Dim objCatalog As New AggregateCatalog
objCatalog.Catalogs.Add(New DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory & "bin"))
Dim container As New CompositionContainer(objCatalog)
container.ComposeParts(Me)
Catch ex As Exception
If m_objLog IsNot Nothing Then
m_objLog.writeError(ex)
End If
End Try
End Sub
End Class
So my main question can be broken into two parts:
Is there any noticeable performance problem with having, say, 20 or so classes that perform composition whenever they are instantiated? I currently only have a few, and if there is a hit it's not noticeable. In other words, do I actually need to change this strategy? It violates DRY because I have a Compose method in every class, but I can learn to live with it.
Is there a better way? How can I handle a single composition in the main application that takes care of populating all of the classes in the plugins, including those not imported in the class performing the main composition?
I've considered the following:
Having all models and utility classes and whatever implement a marker interface, export them all using that interface as a contract, and importing them in the host class, even though the host class doesn't need them. I think this is an even cruddier design than what I have, and I don't want to do it. I'm willing to listen to arguments in favor of this, though.
Having a class in each plugin that needs it that implements IWebHost that acts as a wrapper for the class exported by the main app. I'd still have to do composition in each plugin, but at least it would only be once per plugin. This one seems okay to me.
Thanks in advance for any help you can give, and for reading this whole novel of a question.
I wound up adding a class like the one below to the plugins that need it. I have a project template for plugins, so I'll probably just add this class to that template.
Any class that needs something from the host can access it by calling PluginUtility.Host.
Public Class PluginUtility
<Import()>
Private m_objHost As IWebHost
Private Shared m_objInstance As PluginUtility
Private Sub New()
Compose()
End Sub
Public Shared ReadOnly Property Host As IWebHost
Get
If m_objInstance Is Nothing Then
m_objInstance = New PluginUtility
End If
Return m_objInstance.m_objHost
End Get
End Property
Private Sub Compose()
Try
Dim objCatalog As New AggregateCatalog
objCatalog.Catalogs.Add(New DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory & "bin"))
Dim container As New CompositionContainer(objCatalog)
container.ComposeParts(Me)
Catch ex As Exception
Console.Write("Could not compose to get a reference to the host")
End Try
End Sub
End Class
After listening to the Clean Code Talks, I came to understand that we should use factories to compose objects. So, for example, if a House has a Door and a Door has a DoorKnob, in HouseFactory we create a new DoorKnob and pass it to the constructor of Door, and then pass that new Door object to the constructor of House.
But what about the class that uses the House (say the class name is ABC)? It will depend on the HouseFactory, right? So do we pass the HouseFactory in the constructor of ABC? Won't we have to pass a whole lot of factories in the constructor that way?
Staying with the Door and DoorKnob example, you don't inject a factory - you inject the DooKnob itself:
public class Door
{
private readonly DoorKnob doorKnob;
public Door(DoorKnob doorKnob)
{
if (doorKnob == null)
throw new ArgumentNullException("doorKnob");
this.doorKnob = doorKnob;
}
}
No factories are in sight in this level.
House, on the other hand, depends on Door, but not on DoorKnob:
public class House
{
private readonly Door door;
public House(Door door)
{
if (door == null)
throw new ArgumentNullException("door");
this.door = door;
}
}
This keeps options open until at last you have to compose everything in the application's Composition Root:
var house = new House(new Door(new DoorKnob()));
You can use a DI Container to compose at this level, but you don't have to. No factories are involved.
If you inject too many factories that is a code smell called constructor over-injection that indicates your class is doing too much.
Many containers provide a feature called auto-factories. That means they generate factories of type Func<T>automatically if they know how to generate T.
Castle Windsor has an advanced feature called Typed Factory facilities which generates implementations of a factory interface on-the-fly.
There is also a port of typed factories for Unity in the TecX project.
If you end up using Unity, I have recently implemented an equivalent of Castle Windsor Typed Factories for Unity. You can find the project at https://github.com/PombeirP/Unity.TypedFactories, and the NuGet package at http://nuget.org/packages/Unity.TypedFactories.
The usage is the following:
unityContainer
.RegisterTypedFactory<IFooFactory>()
.ForConcreteType<Foo>();
You just have to create the IFooFactory interface with a method returning IFoo, and the rest is done for you by the library. You can resolve IFooFactory and use it to create IFoo objects straight away.
I am a beginner using castle windsor; and kinda introduced to it with Apress Pro Mvc book. In the project that I am working at; I use castlewindsor controller factory instead of mvc controller factory; so i can have parametrized constructors and i can inject the dependencies.
Is there a way to tell the windsorcontroller factory to inject the values to the properties of the controller class without going through constructor?
The reason I want to do this is because I have Logging dependency; Emailler Dependency; Database Dependency; Theme Engine dEpendency; and I dont want to use this many parameters parameter in the constructor.
By default, when Windsor resolves a service implementation, it will populate all properties with public setters that it can satisfy.
However, take notice that sometime it does make sense to put the dependency resolving in the constructor, for that fact that it guarantees that any instance will always be in a valid state. Consider Unit Testing scenario, where the person writing the test will go crazy about the need to know which dependencies should be supplied. When all dependencies goes into the c'tor, the tester will have no choice but to supply the tested instance with all the required dependencies (as stubs or mocks).
Anyway, as for your question, Windsor support C'tor and property injection by default
Castle Windsor will automatically fill any properties with public setters that it knows how to fill.
This means if you have a class
public MyClass {
public SomeDependency {get; set;}
}
As long as the container is configured to know how to resolve SomeDependency it will attempt to resolve and inject it.
Sometimes I've found this default behavior to be hassle. This facility will give you finer grained control over the process.
I'm designing medium-size website using asp.net mvc technology.
All business logic is organized into IServices (like IDomainService, IUserService, IAuthService, ITrainingService). All services are using IRepositories.
I'm using Ninject 1.5 to wire services with controllers and it seems working perfectly.
There is so far one subject I have no idea how to handle. Some services create contexts (per request) - for instance IDomainService creates DomainContext (per request) which is needed for IUserService.
ITrainingService is used only in TrainingController, which is accessible only by authorized users, and ITrainingService requires UserContext (also per request) to know who is having training.
This is my first project using IoC container.
Is there any design pattern or code-schema how to solve it?
I think I can fill context object using ActionFilters but how to manage their lifetime and where to put them to be accessible for IServices? (in an ellegant way)
I've used Ninject specifically in an MVC application. The way you'd accomplish this with Ninject is in the configuration or binding of your dependencies. When you do this, you specify how you want your object lifetimes to be managed. In most cases of a web app, you objects will be per request as you've indicated in your question.
One thing I've noticed in your question is that your DomainContext is being created by an IDomainService object and is used by other objects. If the domain service object is a sort of factory for a DomainContext, then you don't have much of a problem -- this becomes an exercise of how you configure Ninject to provide concrete objects and inject dependencies.
Here's general guidance on how you would structure your application -- bear in mind I don't have full understanding of your interfaces and classes:
public class GlobalApplication : NinjectHttpApplication {
protected override void RegisterRoutes(RouteCollection routes) {
// Your normal route registration goes here ...
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
// This function is resposible for creating a Ninject kernel. This is where
// the magic starts to happen.
protected override IKernel CreateKernel() {
var modules = new IModule[] {
new AutoWiringModule(),
new AutoControllerModule(
Assembly.GetExecutingAssembly()),
new ServiceModule()
};
return new StandardKernel(modules);
}
}
Note above that the easiest way to get Ninject to work is to derive your application class from the NinjectHttpApplication class. You will need to change your RegisterRoutes to an override method and will also be required to implement a method called CreateKernel. The CreateKernel method is responsible for returning the Ninject kernel which is itself the IoC container.
In the CreateKernel method, the Ninject-provided AutoControllerModule scans assemblies for MVC controller classes and registers them with the container. What this means is that dependencies on those controllers can now be injected by Ninject as it has become the controller provider for the application. The ServiceModule class is one that you need to create to register all of your services with Ninject. I'm guessing it would look something like this:
internal class ServiceModule : StandardModule {
public override void Load() {
Bind<IDomainService>()
.To<MyDomainService>()
.Using<OnePerRequestBehavior>();
Bind<DomainContext>()
.ToMethod( ctx => ctx.Kernel.Get<IDomainService>().CurrentDomainContext )
.Using<OnePerRequestBehavior>();
Bind<IService>()
.To<MyServiceType>()
.Using<OnePerRequestBehavior>();
}
}
Ninject's got a pretty expressive fluent interface for configuration. Note above that each statement basically associates a concrete class with an interface it implements. The "Using" phrase in the statement indicates to the Ninject kernel that the object will live for the life of the request only. So, for example, this means that anytime an IDomainService object is requested from the Ninject kernel during the same request, the same object will be returned.
As for you context objects, I'm taking a stab that your domain service creates these contexts and acts as a factory of sorts. In that regard, I bound instances DomainContext classes above to be produced by getting the value of the a property called CurrentDomainContext off the IDomainService. That's what the lambda above accomplishes. The nice thing about the "ToMethod" binding in Ninject is that you have access to a Ninject activation context object that allows you to resolve objects using the kernel. That's exactly what we do in order to get the current domain context.
The next steps are to ensure your objects accept dependencies properly. For example, you say that ITrainingService is used only in the TrainingController class. So, in that case I would ensure that TrainingController has a constructor that accepts an ITrainingService parameter. In that constructor, you can save the reference to the ITrainingService in a member variable. As in:
public class TrainingController : Controller {
private readonly ITrainingService trainingService;
public TrainingController(ITrainingService trainingService) {
this.trainingService = trainingService;
}
// ... rest of controller implementation ...
}
Remember that Ninject has already registered all of your controllers with the Ninject kernel, so when this controller is created and it's actions are invoked, you'll have a reference to the ITrainingService by way of the trainingService member variable.
Hope this helps you out. Using IoC containers can become quite confusing at times. Note, I highly recommend you check out the Ninject documentation -- it's a very well written introduction to Ninject as well as DI/IoC concepts. I've also left out discussion of the AutoWiringModule shown above; however, Nate Kohari (Ninject's creator) has a good write-up on his blog about this feature.
Good luck!
Im not exactly sure if I understand your problem completely, hopefully this bit of advice can help.
When using an IoC container you let the container handle object lifetime managment. I have only used Castle Windsor and StructureMap for dependency injection so I cant give you a concrete example for how to do this with Ninject.
Looking through the Ninject documentation I think you want to look at Activation Behaviours to specify object lifetime management.
Hope this helps.