Ninject scoping - use same instance across entire graph being constructed - inversion-of-control

Let's say I have the following classes that I want to construct using Ninject, with the arrows showing dependencies.
A > B > D
A > C > D
I want to configure Ninject such that A is transient scoped, i.e. every time you ask Ninject for an A, you get a new one. I also want B and C to be transient, you get a new one of those every time you ask for an A. But I want the D to be reused across both B and C. So every time I request an A, I want Ninject to construct one of each object, not two Ds. But I don't want Ds to be reused across different As.
What is the best way to set this up using Ninject?
Update:
After some more research, it seems like Unity has a PerResolveLifetimeManager which does what I'm looking for. Is there a Ninject equivalent?

Ninject supports four built in object scopes out of the box: Transient, Singleton, Thread, Request.
So there isn't any PerResolveLifetimeManager like scope but you can implement it easily with registering a custom scope with the InScope method.
As it turned out there is an existing Ninject extension: ninject.extensions.namedscope which provides the InCallScope method which is what you are looking for.
However if you want to do it yourself you can do with a custom InScope delegate. Where you can use the main IRequest object for the type A to use it as the scope object:
var kernel = new StandardKernel();
kernel.Bind<A>().ToSelf().InTransientScope();
kernel.Bind<B>().ToSelf().InTransientScope();
kernel.Bind<C>().ToSelf().InTransientScope();
kernel.Bind<D>().ToSelf().InScope(
c =>
{
//use the Request for A as the scope object
var requestForA = c.Request;
while (requestForA != null && requestForA.Service != typeof (A))
{
requestForA = requestForA.ParentRequest;
}
return requestForA;
});
var a1 = kernel.Get<A>();
Assert.AreSame(a1.b.d, a1.c.d);
var a2 = kernel.Get<A>();
Assert.AreSame(a2.b.d, a2.c.d);
Assert.AreNotSame(a1.c.d, a2.c.d);
Where the sample classes are:
public class A
{
public readonly B b;
public readonly C c;
public A(B b, C c) { this.b = b; this.c = c; }
}
public class B
{
public readonly D d;
public B(D d) { this.d = d; }
}
public class C
{
public readonly D d;
public C(D d) { this.d = d; }
}
public class D { }

I found the solution to my specific problem, which is InCallScope that is provided by the ninject.extensions.namedscope extension. This behaves identically to the Unity PerResolveLifetimeManager concept.

One alternative is to construct the dependencies yourself.
var kernel = new StandardKernel();
kernel.Bind<A>().ToMethod(ctx =>
{
var d = new D();
var c = new C(d);
var b = new B(d);
var a = new A(b, c);
return a;
});
This may not be the preferred method, but it will always construct a new instance of A using a new instance of B, C, and D (but reusing the same instance of D for B and C). You can add a call to InTransientScope(), but that is not required as it is the default scope.

Related

Can I force mapstruct to delegate a mapping method to another mapping method or a default (builtin) conversion?

Can I force mapstruct to delegate a mapping method to another mapping method or a default (builtin) conversion?
I basically would like to access a custom mapping method of a uses MapperA inside the custom mapping method of the using MapperX. But I can't get a hold of the injected MapperA inside the custom mapping method of MapperX.
The same is true for builtin conversions. I want to make use of a builtin conversion of mapstruct inside a custom method. Like convert from Date to ZonedDateTime.
e.g.:
#Mapper(componentModel="cdi")
public interface MapperA {
A fromB(B b);
default Q fromR(R r) {
Q q = ..<do some stuff with r>..
return q;
}
}
#Mapper(componentModel="cdi"
uses = MapperA.class
)
public interface MapperX {
default X custom(Y y) {
Date someJavaUtilDate = customDateFromY(y);
//I dont want to code Date->ZonedDateTime myself
//I want mapstruct to do its builtin conversion, so call placeholder:
X.myZonedDateTime = builtinConversionPlaceholder(someJavaUtilDate)
R r = ..<do some stuff with y>..
X.q = usesMapperPlaceholder(r); // injected "uses MapperA" is not directly accessible here?
}
#org.mapstruct.Find_Me_A_Matching_Method_Builtin_Or_In_Uses_Mapper
// will not map properties of Date to ZonedDateTime
// but will use mapstruct builtin conversion code
ZonedDateTime builtinConversionPlaceholder(java.util.Date date);
#org.mapstruct.Find_Me_A_Matching_Method_Builtin_Or_In_Uses_Mapper
// will delegate to MapperA.fromR
Q usesMapperPlaceholder(R r);
}
No it is not possible to force MapStruct to use. build in conversion method.
What you can do is to create some wrapper objects that will be mapped between java.util.Date and ZonedDateTime, MapStruct will then map those using the built in mappings.
e.g.
#Mapper(componentModel="cdi")
public interface MapperA {
A fromB(B b);
default Q fromR(R r) {
Q q = ..<do some stuff with r>..
return q;
}
}
#Mapper(componentModel="cdi"
uses = MapperA.class
)
public abstract class MapperX {
#Inject
MapperA mapperA;
default X custom(Y y) {
Date someJavaUtilDate = customDateFromY(y);
X.myZonedDateTime = toZonedDateTime(someJavaUtilDate).getValue();
R r = ..<do some stuff with y>..
X.q = mapperA.fromR(r);
}
Wrapper<ZonedDateTime> toZonedDateTime(Wrapper<java.util.Date> date);
static class Wrapper<T> {
private T value;
//getters and setters
}
}

Initialize and modify class variables in derived classes

I want to initialize a variable class for my Base class and modify it only in some children classes.
The initialization of this class variable is in the header:
class Base{
public:
Base();
int a = 1;
The header of my derived class is:
class ChildA : public Base{
public:
ChildA ();
int a = 2;
}
Problem
I tried to run this:
Base classe*;
classe = new ChildA();
std::cout << classe->a << std::endl;
The problem is that, instead of printing 2 as I expected, it prints 1 (value initialized in my parent class). For other derived classes, I want classe->a to still return 1.
How can I solve this?
What you are seeing are the results of upcasting - having a base class point to a derived class object.
I highly recommend you read more on the topic, but a simplified picture is that the base class "carries" the whole object (base and derived content), but can access only it's original, own content. This is why you see a value from the base class rather than the derived class.
Lippman's C++ Primer has a very comprehensive explanation of upcasting, downcasting, object slicing, and other inheritance-related concepts. This includes implementing virtual functions which give you the functionality to invoke derived class functions through an interface that's common with base.
|----------------|-----------------|
| a (for Base) | a (for ChildA) |
|----------------|-----------------|
\________________/
^
|_ classe
Sorry if my drawing is not that good! As you can see in the above picture, when you create an object of type ChildA, this object contains a part for keeping the data members of the base class (i.e. Base) and another part for the data members of derived class (i.e. ChildA). Considering the fact that you have a pointer to the base class (i.e. classe), this pointer only allows you to access the base member variables and methods. So calling classe->a, returns the Base::a for you, that is 1.
If you change the type of classe pointer into ChildA, in that case calling classe->a will return 2, because it refers to the a inside the derived class, i.e. ChildA::a.
For other derived classes, I want classe->a to still return 1. How can
I solve this?
If you need in some derived classes to access different as, it is better to have a virtual function in the base class and override the base function if needed:
class Base {
public:
Base() {}
virtual int getA() { return a; }
private:
int a = 1;
};
class ChildA : public Base
{
public:
ChildA() {}
int a = 2;
};
class ChildB : public Base
{
public:
ChildB() {}
int getA() { return a; }
private:
int a = 2;
};
Now by calling getA() on a pointer of Base or ChildA, you will have 1, but calling getA on an object of type ChildB will return 2.

Difference between assign values for the variables of a class [duplicate]

This question already has answers here:
Should I initialize variable within constructor or outside constructor [duplicate]
(11 answers)
Closed 6 years ago.
What is the difference between below 2 ways of assigning values for variables of a class.
Class A{
Private Variable v = someValue;
}
vs
Class A{
private Variable v;
//constructor
public A(){
this.v = someValue;
}
}
Can someone please explain?
There is no real difference from a code execution point of view.
As a previous answer says, I prefer declaring the variable outside of the constructor; for example:
public class A {
private int aValue = 100;
}
Instead of
public class A {
private int aValue;
public A() {
this.aValue = 100;
}
}
The reason being that if you have multiple constructors, you do not have to keep writing this.aValue = 100; and you are unable to "forget" to initialize the variable in a constructor.
As others have said however, there are times when it is better to initialize the variable in the constructor.
If it will change based on values passed to it via the constructor, obviously initialize it there.
If the variable you are initializing may throw an error and you need to use try / catch - it is clearly better to initialize it in the constructor
If you are working on a team that uses a specific coding standard and they require you to initialize your variables in the constructor, you should do so.
Given freedom and none of the above, I still declare it at the top - makes it much easier to find all of your variables in one place (in my experience).
See this duplicate answer: https://stackoverflow.com/a/3919225/1274820
What is the difference between below 2 ways of assigning values for
variables of a class.
Generally nothing, but ...
class constructor is an entry point when creating a new instance, so all assignments should be done there for readability and maintainability.
When you want create a new instance you start reading a source code at the constructor. Here is an example. All informations about new instance are in one proper place.
public class C {
private int aValue;
private int bValue;
private int cValue;
private int dValue;
public C(int a, int b) {
this.aValue = a;
this.bValue = b;
this.cValue = a * b;
this.dValue = 1000;
}
}
If you look at the MSIL of this class:
namespace Demo
{
public class MyClass
{
private string str = "hello world";
private int b;
public MyClass(int b)
{
this.b = b;
}
}
}
.method public hidebysig specialname rtspecialname
instance void .ctor(int32 b) cil managed
{
// Code size 25 (0x19)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldstr "hello world"
IL_0006: stfld string Demo.MyClass::str <---- RIGHT HERE
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: ldarg.0
IL_0012: ldarg.1
IL_0013: stfld int32 Demo.MyClass::b
IL_0018: ret
} // end of method MyClass::.ctor
You can see that the constructor is "injected" with the assignment of this.str = "hello world".
So once your code is compiled, there is no difference what so ever. Yet, there are quite a few good reasons why you should not do it (user1274820's answer has some them)

Is order of dependencies guaranteed when injecting IEnumerable<T>

I register in container services implementing IMyService.
Do I have any guarantees about their order in
container.Resolve<IEnumerable<IMyService>>
?
Just as extra help for people like me landing on this page... Here is an example how one could do it.
public static class AutofacExtensions
{
private const string OrderString = "WithOrderTag";
private static int OrderCounter;
public static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
WithOrder<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registrationBuilder)
{
return registrationBuilder.WithMetadata(OrderString, Interlocked.Increment(ref OrderCounter));
}
public static IEnumerable<TComponent> ResolveOrdered<TComponent>(this IComponentContext context)
{
return from m in context.Resolve<IEnumerable<Meta<TComponent>>>()
orderby m.Metadata[OrderString]
select m.Value;
}
}
No, there's no ordering guaranteed here. We've considered extensions to enable it but for now it's something to handle manually.
I don't mean to self-promote, but I have also created a package to solve this problem because I had a similar need: https://github.com/mthamil/Autofac.Extras.Ordering
It uses the IOrderedEnumerable<T> interface to declare the need for ordering.
I know this is an old post but to maintain the order of registration, can't we just use PreserveExistingDefaults() during registration?
builder.RegisterInstance(serviceInstance1).As<IService>().PreserveExistingDefaults();
builder.RegisterInstance(serviceInstance2).As<IService>().PreserveExistingDefaults();
// services should be in the same order of registration
var services = builder.Resolve<IEnumberable<IService>>();
I didn't find any fresh information on topic and wrote a test which is as simple as (you'd better write your own):
var cb = new ContainerBuilder();
cb.RegisterType<MyClass1>().As<IInterface>();
// ...
using (var c = cb.Build())
{
using (var l = c.BeginLifetimeScope())
{
var e = l.Resolve<IEnumerable<IInterface>>().ToArray();
var c = l.Resolve<IReadOnlyCollection<IInterface>>();
var l = l.Resolve<IReadOnlyList<IInterface>>();
// check here, ordering is ok
}
}
Ordering was kept for all cases I've come up with. I know it is not reliable, but I think that in the current version of Autofac (4.6.0) ordering is wisely kept.

How non-static is accessible in static context in this program?

I am having confusion with the following code:
class A
{
int x;
static void F(B b) {
b.x = 1; /* Ok,
I want to know how is this ok, in a static block how a non static
instance variables are called because as I know that static block
gets memory at compile time before execution of a single command
while non static at run time and static method accessing a non static
variable which is not created yet please elaborate me on this
*/
}
}
class B: A
{
static void F(B b) {
b.x = 1; // Error, x not accessible
}
}
Nothing gets memory at compile time. Static fields are indeed placed in the static block of memory when the type gets initialized. Call stacks for static methods are allocated at run time exactly like in case of instance methods.
Now, why static methods don't have access to the instance fields. Consider this:
class A {
public int Value;
static int GetValue() {
return Value;
}
}
There you have a class with an instance field and a static method. Now, somewhere else you try this:
var a1 = new A();
a1.Value = 5;
var a2 = new A();
a2.Value = 10;
int result = A.GetValue();
Now, if compiler allowed this, what value would the result get? 5 or 10 or something else? This just doesn't make sense, because static methods are declared for class as a whole and aren't aware of instances of this class. So in the code of static method you don't know how many (if any) instances of this class exist and can't access their instance fields.
Hope this makes a little sense.
Either you changed the code in question a bit or I didn't read very carefully. Seems like it's completely different problem right now. The variable x is indeed not accessible for the class B because of its level of protection (default in C# is private). Class A can modify X because it's declared in class A and visible to its method. Class B can't do it (you must make x protected or public for that).