Ninject: instantiate a service during configuration - ninject

I want to configure my ninject container using conventions AND create instances of all selected services at the same time. My current solution is:
var singletons = new List<Type>();
kernel.Bind(x =>
x.FromThisAssembly() // Scans currently assembly
.SelectAllClasses()
.WithAttribute<SingletonAttribute>()
.Where(type =>
{
var include = MySpecialFilterOfSomeSort(type);
if (include)
{
singletons.Add(type);
}
return include;
}) // Skip any non-conventional bindings
.BindDefaultInterfaces() // Binds the default interface to them
.Configure(c => c.InSingletonScope()) // Object lifetime is current request only
);
singletons.ForEach(s => kernel.Get(s));
MORE
I have an intra-process service bus. Some components are decorated with [Singleton] and will register themselves with the service bus:
// the constructor
public FooEventsListenerComponent(IServiceBus serviceBus) {
serviceBus.Subscribe<FooEvent>(e => HandleFooEvent(e));
}
I need a place in the app to create instances of all the service bus observers. Doing it next to type mapping is convenient (but is it appropriate?) because 1. types are already enumerated, 2. I have an access to the DI container.

In the case you describe i think it would make sense to make service bus registration explicit. To expand on my answer to your other question about conventions:
Create an interface for the listeners:
public interface IServiceBusSubscriber
{
void SubscribeTo(IServiceBus serviceBus);
}
then you can adapt your convention to bind all types which inherit from IServiceBusSubscriber to their default interface (then they must be named like FooServiceBusSubscriber and BarServiceBusSubscriber) or to IServiceBusSubscriber explicitly.
After the kernel is initialized with all bindings just do:
IServiceBus serviceBus = kernel.Get<IServiceBus>();
foreach(IServiceBusSubscriber subscriber in kernel.GetAll<IServiceBusSubscriber>())
{
subscriber.SubscribeTo(serviceBus)
}

Related

NInject: Create instances per user/session on convention binding

In summary:
I've undefined of unknowed IProducerPlugin implementations on several assemblies located on a plugins folder.
I've a Core object stores a list of current registered users.
Core is Composition Root.
So, I need:
To create as many IProducerPlugin inherited class objects as the number of registered users.
When a new user is un/registered I need to create / release these objects.
In order to register my "plugins":
this.Kernel.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom(typeof(Extensibility.IProducerPlugin))
.BindAllInterfaces());
I'm not quite figuring out how to implement this.
Could you help me please?
I'll appreciate a LOT your help.
DI containers in general and Ninject in special are not suitable to add and remove new bindings to the container during runtime. Some, like Autofac, don't even allow adding bindings once the container is created.
Ninject allows adding new bindings at any time, but you cannot, ever, remove them (*from some use cases there's Rebind, but that's not the same).
kernel.Release(object) is not removing the binding, it's only removing all references to the object that it holds.
For example:
var foo = new object();
kernel.Bind<object>().ToConstant(foo);
to allow garbage collecting of foo you can do one of the following:
kernel.Release(foo);
kernel.Dispose(); kernel = null;
and exactly this is what kernel.Release(...) is for. Maybe you could also Release a singleton and thus force ninject to create a new one on the next request. But i don't know whether this really works, and if it does, it certainly is quite an unexpected hack.
So what you should do is manage the list/dictionary yourself. You can bind and inject the list/dictionary/manager what ever you call it using ninject, but you cannot have ninject manager the list itself.
I've managed to do something like that similar using this a IBindingGenerator interface method...
I've used .BindWith<>() binding method...
this.Kernel.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom(typeof(Extensibility.IProducerPlugin))
.BindWith<PluginBindingGenerator<Extensibility.IProducerPlugin>>()
);
I've implemented a IBindingGenerator:
public class PluginBindingGenerator<T> : IBindingGenerator
{
public System.Collections.Generic.IEnumerable<Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, Ninject.Syntax.IBindingRoot bindingRoot)
{
if (type != null && !type.IsAbstract && type.IsClass && typeof(T).IsAssignableFrom(type))
{
Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax<object> syntax = bindingRoot.Bind(typeof(Extensibility.IProducerPlugin)).ToProvider(new PluginProvider());
yield return (Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax<object>)syntax;
}
}
}
public class PluginProvider : IProvider<object>
{
private System.Collections.Generic.Dictionary<Domain.Identity.ClientIdentity, Extensibility.IProducerPlugin> plugins;
And then, the provider:
public PluginProvider()
{
this.plugins = new System.Collections.Generic.Dictionary<Domain.Identity.ClientIdentity, Extensibility.IProducerPlugin>();
}
public object Create(IContext ctx)
{
//... I don't know what to do here...
return objects;
}
public Type Type
{
get { throw new NotImplementedException(); }
}
}

Handling plugins with configuration with Ninject

I'm writing an application where various bits of business logic can sit in separate assemblies, then those bits are used to build an object expecting two interfaces, something like this:
public interface ISubjectSource {}
public interface IStudySource {}
public class Worker
{
public Worker(ISubjectSource subjectSource, IStudySource studySource)
{
....
}
}
The seperate assemblies can contain various implementations of ISubjectSource and IStudySource. Then along with a config file:
"Study1":{
"assemblies":["Compare.Sql.dll"],
"mappingSource":"Compare.Sql.SqlSubjectSource,Compare.Sql",
"studySource":"Compare.Sql.SqlStudySource,Compare.Sql",
}
Which describes what is needed to build to worker for "Study1". My problem arrives when the various sources have their own dependencies (e.g. the Sql Sources take an interface that handles creating a connection whose connection string might come from different files).
So, my question boils down to: How do I tell Ninject that when I create a worker for study1, be sure it gets these objects, but when I create a worker for Study2, it gets this other set of objects?
Here's what we do:
We've got an interface IPlugin, with an identifier and an enumerable of modules.
public interface IPlugin
{
string Identification { get; }
IEnumerable<Type> Modules { get; }
}
The Types in Modules must all be inheriting from NinjectModule. Identification is what you refer to in your configuration, like "i want to use plugin SQLStudySource" or "i want to use plugin FileStudySource".
Then we are using https://github.com/ninject/ninject.extensions.conventions to bind all IPlugin implementations from a specific set of assemblies (like all assemblies in the plugin folder):
this.Bind(x => x.FromAssembliesInPath("foo")
.SelectAllClasses()
.InheritedFrom<IPlugin>()
.BindTo<IPlugin>());
Next you activate plugins (or rather their modules, respectively), according to configuration:
IEnumerable<Type> activatedPluginModules = kernel
.GetAll<IPlugin>()
.Where(plugin => configuration.ActivatedPluginIdentifications.Contains(plugin.Identification)
.SelectMany(x => x.Modules)
.Distinct();
foreach(Type module in activatedPluginModules)
{
kernel.Load(module);
}
That's about it.

WCF Attribute injection using an IOC Container

Using ASP.NET MVC I am able to replace the FilterProvider as so
var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
FilterProviders.Providers.Remove(oldProvider);
FilterProviders.Providers.Add(new CustomFilterProvider(_container));
Using my own custom provider. It does not give me the ability to use a factory pattern to create the controller filter attributes but I do get the ability to use property injection to set dependencies the attributes may need using the container.
Is it possible to do something similar using WCF so that I can inject dependencies (property injection is fine) into my user defined classes that derive from Attribute that I use on my service methods (the services are created using IOC)?
I am using CastleWindsors WcfFacility, but a generalised solution (that applied to any container) would probably be a better answer.
One way to do this is to use the containers OnCreate method or similar and do something like the following at registration
Container.Register(Component.For<IMyService>().ImplementedBy<MyService>().OnCreate(WireUpAttibutes).LifeStyle.Transient);
then have the following methods
private static void WireUpAttibutes<T>(IKernel kernel, T instance) {
var attributes = instance.GetType().GetCustomAttributes(typeof(MyAttribute), false);
foreach (var attribute in attributes) {
WireUp(kernel, attribute.GetType(), attribute);
}
}
private static void WireUp(IKernel kernel, Type type, object instance) {
var properties = type.GetProperties().Where(p => p.CanWrite && p.PropertyType.IsPublic);
foreach (var propertyInfo in properties.Where(propertyInfo => kernel.HasComponent(propertyInfo.PropertyType))) {
propertyInfo.SetValue(instance, kernel.Resolve(propertyInfo.PropertyType), null);
}
}

Autofac - Lifetime and modules

Problem (abstract)
Given a module which registers dependency X. The dependency X has a different lifetime in a MVC3 app (lifetime per HttpRequest) then in a console application (dependency per lifetimescope with a name). Where or how to specify the lifetime of dependency X?
Case
I've put all my database related code in a assembly with a module in it which registers all repositories. Now the ISession (Nhibernate) registration is also in the module.
ISession is dependency X (in the given problem case). ISession has different lifetime in a MVC3 app (lifetime per request) then in a console app where I define a named lifetimescope.
Should the registration of ISession be outside the module? Would be strange since it's an implementation detail.
What is the best case to do here? Design flaw or are there smart constructions for this :) ?
Given your use case description, I'd say you have a few of options.
First, you could just have each application register their own set of dependencies including lifetime scope. Having one or two "duplicate" pieces of code in this respect isn't that big of a deal considering the differences between the application and the fact that the registrations appear fairly small.
Second, you could wrap the common part (minus lifetime scope) into a ContainerBuilder extension method that could be used in each application. It would still mean each app has a little "duplicate code" but the common logic would be wrapped in a simple extension.
public static IRegistrationBuilder<TLimit, ScanningActivatorData, DynamicRegistrationStyle>
RegisterConnection<TLimit, ScanningActivatorData, DynamicRegistrationStyle>(this ContainerBuilder builder)
{
// Put the common logic here:
builder.Register(...).AsImplementedInterfaces();
}
Consuming such an extension in each app would look like:
builder.RegisterConnection().InstancePerHttpRequest();
// or
builder.RegisterConnection().InstancePerLifetimeScope();
Finally, if you know it's either web or non-web, you could make a custom module that handles the switch:
public class ConnectionModule : Autofac.Module
{
bool _isWeb;
public ConnectionModule(bool isWeb)
{
this._isWeb = isWeb;
}
protected override void Load(ContainerBuilder builder)
{
var reg = builder.Register(...).AsImplementedInterfaces();
if(this._isWeb)
{
reg.InstancePerHttpRequest();
}
else
{
reg.InstancePerLifetimeScope();
}
}
}
In each application, you could then register the module:
// Web application:
builder.RegisterModule(new ConnectionModule(true));
// Non-web application:
builder.RegisterModule(new ConnectionModule(false));
Alternatively, you mentioned your lifetime scope in your other apps has a name. You could make your module take the name:
public class ConnectionModule : Autofac.Module
{
object _scopeTag;
public ConnectionModule(object scopeTag)
{
this._scopeTag = scopeTag;
}
protected override void Load(ContainerBuilder builder)
{
var reg = builder.Register(...)
.AsImplementedInterfaces()
.InstancePerMatchingLifetimeScope(this._scopeTag);
}
}
Consumption is similar:
// Web application (using the standard tag normally provided):
builder.RegisterModule(new ConnectionModule("httpRequest"));
// Non-web application (using your custom scope name):
builder.RegisterModule(new ConnectionModule("yourOtherScopeName"));
I would recommend against simply using InstancePerLifetimeScope in a web application unless that's actually what you intend. As noted in other answers/comments, InstancePerHttpRequest uses a specific named lifetime scope so that it's safe to create child lifetime scopes; using InstancePerLifetimeScope doesn't have such a restriction so you'll actually get one connection per child scope rather than one connection for the request. I, personally, don't assume that other developers won't make use of child lifetime scopes (which is a recommended practice), so in my applications I'm very specific. If you're in total control of your application and you can assure that you aren't creating additional child scopes or that you actually do want one connection per scope, then maybe InstancePerLifetimeScope will solve your problem.
It's common practice to use a one connection per http request. That being the case, connections would be registered using .InstansePerLifetimeScope(). For example, you might do something like:
builder
.Register(c => {
var conn = new SqlConnection(GetConnectionString());
conn.Open();
return conn;
})
.AsImplementedInterfaces()
.InstancePerLifetimeScope();

WCF service with multiple implementations of dependency

I have a WCF service that will be called from a various clients.
Internally the WCF service uses an ISomething. There are multiple implementations of this interface and I need some clients to use one implementation and other clients to use a different implementation.
In addition, I am using Unity and an IoC container. I would typically set up a custom factory to allow the wcf service itself to be resolved along with its dependency graph, but if I have multiple implementations of a dependency, I do not think I can go with this approach and would have to resort to resolving the ISomething within the service (effectively using Unity as a service locator) which is not ideal.
So I need to work out
(1) how to specify which implementation of ISomething a client needs (eg. use a header, pass implementation string in each method, host multiple endpoints etc.)
(2) how Unity fits in?
One option is to write a Decorator that performs the selection for you:
public class RoutingSomething : ISomething
{
private readonly ISomeContext ctx;
private readonly ISomething s1;
private readonly ISomething s2;
private readonly ISomething s3;
public RoutingSomething(ISomeContext ctx)
{
this.ctx = ctx;
// An even better design would be to inject these too
this.s1 = new BarSomething();
this.s2 = new BazSomething();
this.s3 = new QuxSomething();
}
// Assuming ISomething has a Foo method:
public void Foo()
{
if(this.ctx.Bar())
{
this.s1.Foo();
return;
}
if(this.ctx.Baz())
{
this.s2.Foo();
return;
}
if(this.ctx.Qux())
{
this.s3.Foo();
return;
}
}
}
You could generalize this so that ISomeContext is simply an Abstract Factory of ISomething. This then begins to turn into the general solution to varying dependencies based on run-time context.
You can now register RoutingSomething in Unity in addition to your other components. When the container resolves the service, it'll inject an instance of RoutingSomething into it.