How to make Ninject choose a specific constructor without using InjectAttribute? - ninject

1) Is there a way to make Ninject select a specific constructor in code other than applying the InjectAttribute?
2) Also, how do I supply values for these arguments of the constructor?
3) Can I override these argument values on resolution or creation of the object, i.e. when I call kernel.Get<T>()?

There's the ToConstructor binding method:
Bind<IMyService>().ToConstructor(
ctorArg => new MyService(ctorArg.Inject<IFoo>()));
You can specify values on binding using 3 mechanisms:
create a binding for the dependency (Bind<IFoo>().To<Foo>())
specify a constructor argument (add a WithConstructorArgument(typeof(IFoo), new Foo()) to the end of the binding)
if i remember correctly, you can also specify it in the ToConstructor syntax like ToConstructor(ctorArg => new MyService(myFoo));
(Also see http://www.planetgeek.ch/2011/05/28/ninject-constructor-selection-preview/)
You can specify values on resolution by passing a ConstructorArgument or, preferrably, a TypeMatchingConstructorArgument (or some custom IParameter) to the resolution:
IResolutionRoot.Get<IMyService>(new TypedConstructorArgument(
typeof(IFoo),
(ctx, target) => myFooInstance));

Related

Puppet module level hiera for setting dependency values

I have created a puppet module and wish to use (hiera 5) module-level hiera to set values for dependencies. I have created a hiera.yaml, data dir and common.yaml. However, module hiera values do not appear to be passed to the dependencies, and I have to set the hiera at the environment level instead (which is then not self contained within the module).
It appears that hiera keys only resolve with the local module prefix.
The dependency I am targeting is fervid/secure_linux_cis and I need to set some hiera for it's classes with 'enforced => false'. Doing this in a manifest isn't 100% effective as a few classes present as duplicate resources.
Essentially, what I want to be able to do in my module's common.yaml is:
---
my::module::key1: 'value'
secure_linux_cis::redhat7::cis_1_1_2:enforced: false
Using the above example, I can resolve the my::module value but the dependency secure_linux_cis value is ignored.
Is there a way to get module level hiera to pass values to a dependency?
Is there a way to get module level hiera to pass values to a dependency?
Not directly, no. Automatic data binding performs Hiera lookups in the context of the class whose parameters are being looked up, not that of the one declaring it. In your case, then, it is the hiera data of module secure_linux_cis that will be consulted for default values for the parameters of class secure_linux_cis::redhat7::cis_1_1_2.
If you are willing to risk using a resource-like declaration of that class, then you should be able to do something along these lines:
class my::module(
String $key1
) {
$cis112_enforced = lookup('secure_linux_cis::redhat7::cis_1_1_2:enforced', Boolean, undef, false)
class { 'secure_linux_cis::redhat7::cis_1_1_2': enforced => $cis112_enforced }
}
Of course, that carries all the risks attending resource-like class declarations. I don't actually recommend it. You could consider instead setting the parameter in a per-node level of the environment-level data. You might also consider looking at the Roles & Profiles pattern, for resource-like class declarations make a little bit more sense in a profile class.
secure_linux_cis::redhat7::cis_1_1_2::enforced
This should work. You missed one : in your example.

Jackson 2.5+: what JsonSerializer methods must be overridden by wrapping JsonSerializer returned from BeanSerializerModifier.modifySerializer(...)?

Using Jackson 2.5+, what JsonSerializer methods must be overridden by a wrapping JsonSerializer returned from:
BeanSerializerModifier.modifySerializer(SerializationConfig sc, BeanDescription bd, JsonSerializer<?> js)
I'm definitely overriding serialize(...), because I'm filtering out some objects from being serialized based on the values of their properties in that override. Otherwise, if the object isn't filtered out by its property values, I serialize normally by calling js.serialize(...), where js is the JsonSerializer that was passed as an argument to modifySerializer.
But I'm not sure if I should also override any of the following other JsonSerializer methods:
getDelegatee()
replaceDelegatee(...)
isUnwrappingSerializer()
unwrappingSerializer(...)
handledType()
usesObjectId()
isEmpty(T)
isEmpty(SerializerProvider, T)
acceptJsonFormatVisitor(...)
serializeWithType(...)
e.g., Should getDelegatee() return js?
Why would I want to allow replaceDelegatee(...) to replace js as the delegatee? If I should allow this, then I'd have to save js to a field so I could replace it.
As per my other answer, some of those you do want to (re)define, others not. (1), (8), (9) and (10) do make sense; (7) is deprecated and not needed any more. (5) should be defined by base class (at least if extending StdSerailizer), if not defined, should be defined mostly because it is used by some error reporting.
(3) and (4) are things you may want to support, if you want #JsonUnwrapped to be implemented for the type. If you are delegating to a standard POJO serializer, this is probably true. If not implemented, #JsonUnwrapped will basically have no effect on properties with your custom serializer.
(6) applies similarly for #JsonIdentityInfo; but note that object identity may be tricky to handle with delegation model.
As to delegatee replacement... I would not worry about that one. I think it was added speculatively, and is not actually used by the framework.

Ninject dynamic multiple constructor arguments

I have been implementing Dependency Injection into an existing Winforms project and it has been going well so far, however I want to generalise the calling of the Forms, specifically the varying quantity of constructor parameters.
My code is as follows:
Public Shared Function GetForm(formObject As BaseObject, _
parameters As Dictionary(Of String, Object)) As Form
Select Case formObject.GetType()
Case GetType(Production.Task)
Return SMKernel.Kernel.Get(Of Forms.Production.Domain.ManageTask) _
(New Parameters.ConstructorArgument() _
{New Parameters.ConstructorArgument("task", _
CType(formObject, Production.RequiredTask))})
End Select
End Function
This works fine, the interface(s) are injected correctly, the constructor parameter "task" is populated and the Form works as expected.
As you can see I have a Dictionary that can contain several parameters which I need to add to the ConstructorArgument part of the Get method. Looking at the IntelliSense, I should be able to pass in an array of ConstructorArgument objects, however no matter what I have tried, it doesn't seem to work for one reason or another.
How do you accomplish this in Ninject if it is at all possible. If this way isn't possible, how can you pass multiple parameters into a Form's constructor via Ninject?
Use the already provided ResolutionExtensions
public static T Get<T>(this IResolutionRoot root, params IParameter[] parameters)
Then combine it with LINQ
Kernel.Get(parameters.Select(kvp => new ConstructorArgument(kvp.Key, kvp.Value)).ToArray())
Provide more details and we might give you are more elegant approach.

Binding interface via ToMethod to a method with a parameter

I think what I'm looking for is something very simple, yet I am unable to find any examples.
I'd like to use Ninject to create an object by having Ninject call a factory method with a parameter specified and not injected during the actual request to instantiate the object:
Request for an object here:
StandardKernel.Get<ISomeInteface>(new Ninject.Parameters.Parameter("dataContext", dataContext, true));
And I'd like to map the ISomeInterface to a method that is expecting a value to be passed to it at runtime.
Mapping an interface here:
Kernel.Bind<ISomeInterface>().ToMethod(SomeObject.Create(--> `what do I put here?`));
Is this possible? If so, how do I properly map my interface?
Thanks!
ToMethod(ctx =>
SomeObject.Create(
(IDataContext)ctx.Parameters.Single(p =>p.Name == "dataContext")
.GetValue(ctx, null))
But you should rethink your design to avoid calling Get from anywhere else than your composite root.

How do you call a delegate exported via MEF with late binding?

What I'm trying to do is for this to work:
GetMethod(Key key)(...some arguments...)
The "...some arguments..." varies between each call of GetMethod, including in number of parameters, so there is no specific Action<...> that I can use.
Now the GetMethod looks through the argument list to find a match within a list of Tuple and returns the second argument of the Tuple, which is the dynamic. This list was created using MEF by
<some CompositionContainer>.GetExports(new ImportDefinition(a => true, "...", ImportCardinality.ZeroOrMore, true, false))
.Select(e => (Tuple<Key, dynamic>)Tuple.Create((Key)e.Metadata["Key"], e.Value))
.ToList();
Now, it seems that the second item in the typle isn't actually an Action of the appropriate type, but rather a ExportedDelegate. Is there any way to make so that the second item is actually a correct Action, so that GetMethod(...)(...) actually does work?
Call ExportedDelegate.CreateDelegate. Pass in the type of delegate you want (ie Action). MEF uses ExportedDelegate so that you aren't restricted to using Action<> and Func<> delegates, but can use any delegate type with a matching signature.
You also probably need to specify the contract name in the constraint you pass to the ImportDefinition constructor, instead of just passing a => true.