Ninject with Windows Application
D

4

6

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.

Depside answered 14/8, 2010 at 19:48 Comment(0)
S
5

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.

Stork answered 14/8, 2010 at 20:45 Comment(4)
+1 and related link kohari.org/2009/03/06/… is a must read for understanding Ninject 2.0 scopesVeinstone
After reading linked articles, I now better understand how I can control the lifetime of dependent objects injected. This is good but without a great architecture, it can be awkward to maintain. It seem that very few people on the web gives tricks about how to design a good windows application and how to start the scope of object in winform always while keeping in mind that many other forms can works together. I use LightSpeed of Mindscape and the UnitOfWork use cache and when you have many winforms that works together, data must often be shared. Any body have a concrete sample of project?Depside
@Samuel, To be honest, I have not seen much in the way of concrete sample applications that show Windows Forms with ORM and UnitOfWork employed throughout a well architected application. I certainly would like to see them myself if I could ever find any.Stork
Thank you very much for your answer. I will search a sample project with these specifications and I will send it here.Depside
D
3

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
Depside answered 5/1, 2011 at 14:29 Comment(1)
Good to hear you feel you have an answer. As long as you have full lambda methods (incomplete in VB until ver X (2010?), one typically uses Bind.ToMethod() - if you actually have something complex enough to require a class, typically you should be doing that as a container-agnostic thing as its part of your domain logic. But it definitely has a place alright, esp if you dont have proper lambdas.Veinstone
V
2

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.

Veinstone answered 15/8, 2010 at 0:14 Comment(0)
M
0

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.

Methodize answered 15/12, 2010 at 6:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.