NInject: Create instances per user/session on convention binding - ninject

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(); }
}
}

Related

How do I mock Func<T> factory dependency to return different objects using AutoMock?

I'm trying to write a test for a class that has a constructor dependency on Func<T>. In order to complete successfully the function under test needs to create a number of separate objects of type T.
When running in production, AutoFac generates a new T every time factory() is called, however when writing a test using AutoMock it returns the same object when it is called again.
Test case below showing the difference in behaviour when using AutoFac and AutoMock. I'd expect both of these to pass, but the AutoMock one fails.
public class TestClass
{
private readonly Func<TestDep> factory;
public TestClass(Func<TestDep> factory)
{
this.factory = factory;
}
public TestDep Get()
{
return factory();
}
}
public class TestDep
{}
[TestMethod()]
public void TestIt()
{
using var autoMock = AutoMock.GetStrict();
var testClass = autoMock.Create<TestClass>();
var obj1 = testClass.Get();
var obj2 = testClass.Get();
Assert.AreNotEqual(obj1, obj2);
}
[TestMethod()]
public void TestIt2()
{
var builder = new ContainerBuilder();
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
var container = builder.Build();
var testClass = container.Resolve<TestClass>();
var obj1 = testClass.Get();
var obj2 = testClass.Get();
Assert.AreNotEqual(obj1, obj2);
}
AutoMock (from the Autofac.Extras.Moq package) is primarily useful for setting up complex mocks. Which is to say, you have a single object with a lot of dependencies and it's really hard to set that object up because it doesn't have a parameterless constructor. Moq doesn't let you set up objects with constructor parameters by default, so having something that fills the gap is useful.
However, the mocks you get from it are treated like any other mock you might get from Moq. When you set up a mock instance with Moq, you're not getting a new one every time unless you also implement the factory logic yourself.
AutoMock is not for mocking Autofac behavior. The Func<T> support where Autofac calls a resolve operation on every call to the Func<T> - that's Autofac, not Moq.
It makes sense for AutoMock to use InstancePerLifetimeScope because, just like setting up mocks with plain Moq, you need to be able to get the mock instance back to configure it and validate against it. It would be much harder if it was new every time.
Obviously there are ways to work around that, and with a non-trivial amount of breaking changes you could probably implement InstancePerDependency semantics in there, but there's really not much value in doing that at this point since that's not really what this is for... and you could always create two different AutoMock instances to get two different mocks.
A much better way to go, in general, is to provide useful abstractions and use Autofac with mocks in the container.
For example, say you have something like...
public class ThingToTest
{
public ThingToTest(PackageSender sender) { /* ... */ }
}
public class PackageSender
{
public PackageSender(AddressChecker checker, DataContext context) { /* ... */ }
}
public class AddressChecker { }
public class DataContext { }
If you're trying to set up ThingToTest, you can see how also setting up a PackageSender is going to be complex, and you'd likely want something like AutoMock to handle that.
However, you can make your life easier by introducing an interface there.
public class ThingToTest
{
public ThingToTest(IPackageSender sender) { /* ... */ }
}
public interface IPackageSender { }
public class PackageSender : IPackageSender { }
By hiding all the complexity behind the interface, you now can mock just IPackageSender using plain Moq (or whatever other mocking framework you like, or even creating a manual stub implementation). You wouldn't even need to include Autofac in the mix because you could mock the dependency directly and pass it in.
Point being, you can design your way into making testing and setup easier, which is why, in the comments on your question, I asked why you were doing things that way (which, at the time of this writing, never did get answered). I would strongly recommend designing things to be easier to test if possible.

DunglasApiBundle - Trying to get the bundle to use Named Constructors rather than public constructor

I'm using the Dunglas api-platform bundle (https://github.com/api-platform/api-platform) for a new app.
Setup and installation went fine, GET requests are working.
While trying to create new objects using POST requests, I received errors about having a private constructor. My models are all made using a private constructor, and using named constructors instead.
Ideally i'm either looking for a way to have the bundle call my Named constructors, ... or someone to tell me my approach is completely wrong.
Services.yml
services:
resource.player:
parent: "api.resource"
arguments: [ "Name\\Space\\Player" ]
tags: [ { name: "api.resource" } ]
Player Object
class Player
{
private $name;
private function __construct()
{
}
public static function withName($playerName)
{
$player = new Player();
$player->name = $playerName;
return $player;
}
public function getName()
{
return $this->name;
}
}
Settings are pretty much all out of the box, following the introduction and setup in the documentation. I've skimmed through the Factory thing briefly - hoping that i'd be able to use a factory to create the objects, allowing me to call my own named constructors - but that doesn't seem to do what i think it does.
Any input regarding the use, boundaries or the setup is well appreciated.
API Platform (like most Symfony and Doctrine related libraries) is not designed to work with immutable objects like this one.
I suggest to create a typical mutable Entity as suggested in the doc:
class Player
{
private $name;
public static function setName($playerName)
{
$this->name = $playerName;
}
public function getName()
{
return $this->name;
}
}
If you really want to keep your immutable model, you'll need to implement yourself the Symfony\Component\PropertyAccess\PropertyAccessorInterface and use a CompilerPass to make API Platform using your own implementation. You will probably need to submit a patch to API Platform and to the Symfony Serializer Component to update the reference of the given object too because currently, both serializers actually update the current object and will not use the new instance returned by your with method.
I strongly encourage you to switch to typical mutable entities.

Changing IoC provider on an Caliburn Micro WPF Application

I've an existing WPF application based on caliburn micro MVVM pattern which was using Ideablade/cocktail for accessing to database. Now I've switched to servicestack and I was keeping on cocktail just for the composition pattern. Since I've noticed it takes quite a bit long to start the application I've done some test and Ninject performs better.
I find extremly usefull the MEF approach of defining the Export/ImportingConstrucor approach but and I was wondering how I can have it with Ninject... is it possible?
In my current implementation I've something as
[Export(typeof(IMyInterface))]
[Export(typeof(MyFirstViewModel))]
public class MyFirstViewModel:IMyInterface
{
[ImportingConstructor]
public MyFirstViewModel(IEventAggregator eventAggregator)ù
{
}
}
I've seend that in ninject I've to define something as
mKernel.Bind<MyFirstViewModel>().To<MyFirstViewModel>();
mKernel.Bind<MyFirstViewModel>().To<MyFirstViewModel>();
Can it be automatic?
Can I also define a funct to resolve when not found?
Thanks
StackTrace :
at Caliburn.Micro.IoC.<.cctor>b__0(Type service, String key) in c:\Users\Rob\Documents \CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\IoC.cs:line 13
at Caliburn.Micro.IoC.Get[T](String key) in c:\Users\Rob\Documents\CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\IoC.cs:line 32
at myApp.Modules.Core.Framework.ViewModels.myAppScreenBase`1..ctor() in c:\Projects\myApp\branches\myApp-branch-20140526\myApp\Core\Framework\ViewModels\myAppScreenBase.cs:line 44
at myApp.Modules.Core.Framework.ViewModels.myAppSimpleScreen`1..ctor() in c:\Projects\myApp\branches\myApp-branch-20140526\myApp\Core\Framework\ViewModels\myAppSimpleScreen.cs:line 8
at myApp.Modules.AdE.ViewModels.CMATCLIDDelegheViewModel..ctor(IAdERepository repository, IDialogManager dialogManager, ICommonRepository commonRepository) in c:\Projects\myApp\branches\myApp-branch-20140526\myApp\Modules.AdE\ViewModels\CMATCLIDDelegheViewModel.cs:line 56
at DynamicInjector1033b54d439c44dbaa064db1c7e82f18(Object[] )
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.ResolveInternal(Object scope)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass15.<Resolve>b__f(IBinding binding)
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()
RepositoryExport :
public class RepositoryBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
foreach (var attribute in type.GetCustomAttributes(typeof(RepositoryAttribute), false)
.OfType<RepositoryAttribute>())
{
yield return bindingRoot
.Bind(attribute.ContractType ?? type)
.To(type).InSingletonScope();
}
}
}
but I got this compile error
Error 19 Cannot implicitly convert type 'Ninject.Syntax.IBindingNamedWithOrOnSyntax' to 'Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax'. An explicit conversion exists (are you missing a cast?)
Depending on the configuration of ninject (by default its enabled) you don't need to bind a type to itself, ninject will resolve it automatically. So mKernel.Bind<MyFirstViewModel>().To<MyFirstViewModel>(); is superfluous. Remark: Creating the binding anyway also works.
However, if you want to bind Bar to IFoo or Foo to IFoo you need to bind it.
With it you can tell ninject to look for all types with an [Export] attribute and bind these.
Here comes the ninject conventions extension to the rescue. Get the ninject.extensions.conventions nuget package.
Then create a convention binding:
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.WithAttribute<ExportAttribute>()
.BindWith<ExportBindingGenerator>());
public class ExportBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
foreach (var attribute in type.GetCustomAttributes<ExportAttribute>())
{
yield return bindingRoot
.Bind(attribute.ContractType)
.To(type);
}
}
}
Things get a bit more complicated when you need to also use the [ImportingConstructor] attribute to tell ninject which constructor to use. But i would suppose that you don't need it, since Ninject's auto-constructor-selection. What you can do however is replace all [ImportingConstructor] attributes with Ninject's [Inject] attribute which does exactly the same.
Notes:
You may need to use another method than .FromThisAssembly() to specify all the assemblies which contain the implementation types.
If the implementation types are not public, you need to add IncludeNonePublicTypes() to the convention.

How to Implement Castle Windsor IScopeAccessor to provide NHibernate Session Per ViewModel using LifestyleScoped

I am looking for some help creating an implementation of IScopeAccessor, or finding a new solution, that will allow me to provide an NHibernate session per ViewModel.
I know that Windsor now supports scoped lifestyles as seen (here). However the example creates the special scope with a using block and calling container.resolve within the using.
_container.Register(Component.For<A>().LifestyleScoped());
using (_container.BeginScope())
{
var a1 = _container.Resolve<A>();
var a2 = _container.Resolve<A>();
Assert.AreSame(a1, a2);
}
I can't think of a way to make this work because I don't want to pass around the container and I want the scope to be tied to the ViewModel that gets created, which will happen dynamically as they are needed.
As an alternative it looks like I can create an implementation of IScopeAccessor which, according to Krzysztof Koźmic (here) would allow me to
"... provide any scope you like. Scope is an abstract term here and it can be anything."
Unfortunately I cannot find an implementation of IScopeAccessor that isn't specific to a web based scenario and I am struggling to understand exactly what I need to do to turn "anything" into a valid scope.
I have found an example of exactly what I want to do using Ninject (http://www.emidee.net/index.php/2010/08/23/ninject-use-one-database-session-per-view-model/):
Bind<ISession>().ToMethod(ctx =>
{
var session = ctx.Kernel.Get<....>().BuildSessionFactory().OpenSession();
return session;
})
.InScope(context =>
{
var request = context.Request;
if (typeof(IViewModel).IsAssignableFrom(request.Service))
return request;
while ((request = request.ParentRequest) != null)
if (typeof(IViewModel).IsAssignableFrom(request.Service))
return request;
return new object();
});
In Ninject, the InScope indicates that any instances created by the binding should be reused as long as the object returned by the call back remains alive. Essentially, this call back returns the root level ViewModel (since ViewModels can be nested).
Any thoughts on how I can do the same thing or get the same result using Windsor?
The problem seems to be the place of creation.
If it's all about dependencies of viewmodels being constructed, you could maybe use boud lifestyle, as described in What's new...
Or you could alternatively use your own scope accessor, that is sensitive to viewmodels. for example like this:
public class ViewModelScopeAccessor : IScopeAccessor
{
private IDictionary<Guid, ILifetimeScope> scopes = new Dictionary<Guid, ILifetimeScope>();
private ILifetimeScope defaultScope;
public ViewModelScopeAccessor()
: this(new DefaultLifetimeScope())
{ }
public ViewModelScopeAccessor(ILifetimeScope defaultScope)
{
this.defaultScope = defaultScope;
}
public ILifetimeScope GetScope(CreationContext context)
{
var creator = context.Handler.ComponentModel.Implementation;
var viewModel = creator as IViewModel;
if (viewModel != null)
{
ILifetimeScope scope;
if (!scopes.TryGetValue(viewModel.UID, out scope))
{
scope = new DefaultLifetimeScope();
scopes[viewModel.UID] = scope;
}
return scope;
}
else
{
return defaultScope;
}
}
public void Dispose()
{
foreach (var scope in scopes)
{
scope.Value.Dispose();
}
defaultScope.Dispose();
scopes.Clear();
}
}
for the following viewmodel interface :
public interface IViewModel
{
string DisplayName { get; }
Guid UID { get; }
}
You of course could compare the viewmodels in other ways, it's just an example.
The drawback of both, the bound lifestyle and that scope accessor, is, that it won't work, if you use a typed factory inside your viewmodel, to lazily construct objects, since the scope accessor has no idea, from which object/method its factory method was called. But I think is is a general .NET issue, since a method does actually never know, from where it has been called.
So, you could then use your own factories, that produce only one instance per factory instance and make them scoped to your viewmodels too.
Hope this helps.

If not a singleton, then what?

So I'm working on a middleware layer.
I'm consuming a COM DLL that deals with the low level hardware interaction, and providing an interface for the UI to do IO with the hardware.
As part of the design of my layer, we put in a contextmanager that arranges the various pieces of hardware to produce contexts that our application can work with.
So I want to guarantee that a developer that is working with my code has a single context manager to work with and then inside that context manager I can guarantee that we only allocate 1 work queue per hardware device.
Just to complicate this there is some initialization that must be done before I can start adding in hardware devices. Something that would be simple if not for the fact that typically you only access a singleton via a readonly property.
I know the singleton pattern can make alot of things difficult because of it's global accessibility. I really do not want, nor need for this class to have the global availability of a singleton, I just want the guarantee that only one will be created inside the app.
For that would I be crazy to do something like this, to basically give my singleton a constructor:
public class MySingleton
{
private static MySingleton _MySingleton;
private static object singletonLock = new object();
private MySingleton(int foo1, string foo2)
{
//do init stuff
}
public static MySingleton StartSingleton(int foo1, string foo2)
{
try
{
Monitor.Enter(singletonLock);
if (_MySingleton == null)
{
_MySingleton = new MySingleton(foo1, foo2);
}
else
throw new Exception("Singleton already initialized");
}
finally
{
Monitor.Exit(singletonLock);
}
return _MySingleton;
}
public static MySingleton Instance
{
get
{
try
{
Monitor.Enter(singletonLock);
if (_MySingleton == null)
{
throw new Exception("Singleton must be Initialized");
}
}
finally
{
Monitor.Exit(singletonLock);
}
return _MySingleton;
}
}
}
It's not crazy code but it is a singleton anyway. If you remove Instance property then it won't be singleton anymore.
Global accessibility is not all that makes singletons nasty. What makes them nasty is that they are used all through the system directly without you being able to track all those usages. That's why it is such a nightmare in multi-threading code, that's why it is so hard to unit test anything with singletons inside.
So if it is your code I'd recommend creating just one object during application initialization and pass it around with dependency injection or as plain constructor argument. If it is a library, you can either check in constructor if it is first object being created or not and throw an exception or you can go with static constructor as you did but without Instance property, forcing developers to pass instance around.
As always, you can just create singleton, after all all it matters is that product works and customers enjoy using it, singletons or no singletons doesn't really matter.
You wouldn't be crazy. A singleton avoids the drawbacks of global variables by virtue of being namespaced. Even though it is globally accessible via a static function call, it is not a global variable. And further, it is accessed via a namespace, so noone is likely to put it in a global var called temp, then later assign something else to temp. They should always get a local reference to it by doing
MySingleton singletonRef = MySingleton.Instance();
when their scope closes, the reference dies, and so it's not a global variable.
So if I just need to garuntee that you can only create one version of my object then something like this would work:
public class MySingleton
{
private static int objectCount = 0;
private static object singletonLock = new object();
public MySingleton(int foo1, string foo2)
{
try{
Monitor.Enter(singletonLock);
if (objectCount != 0)
{
throw new Exception("MySingleton Already exsists");
}
else
{
objectCount++;
}
}
finally{
Monitor.Exit(singletonLock);
}
//do initialization stuff
}
}
obviously not a true singleton anymore.