Swinject factory closure called multiple times when object scope is container - ios

I'm trying to register CoreDataStack as a single instance on a shared container with object scope .container, but its factory closure called multiple times and when I debug memory graph in Xcode several instances of the object are created even when the returned object is not value-type!
Swinject documentation:
The object scope is ignored if the factory closure returns a value type because its instance is never shared per the Swift specification.
What is the root cause of this strange behavior?

Registering a service with a name solve the issue and no more instances created
container.register(CoreDataStack.self, name: "CoreDataStack") {
DefaultCoreDataStack(modelName: "name")
}.inObjectScope(.container)

Related

Can I recall a Stateful Class while in the class

I am passing the first object of a List myList[] from Class A to a stateful class B that is a separate page in my application. The passed object is therefore created as immutable since flutter prefers immutable classes and immutable classes need const constructors, variables in which must be final. In the B class, I later call a function that modifies the object from the List, and objects in a list aren't immutable. But since I have already passed the object, I can't see the updated value. I solved this issue by making: the value - non-final, the constructor - not const, and therefore the class - mutable. Another way I could solve it is to just use global variables instead.
My question is - Is there a way to reinstantiate class B? I.e., go to class A, navigate to page B by passing the (now updated) first object of List myList[] ?
Perhaps you could try using a State manager like Provider. From my understanding, you're trying to share variables across different widgets. Using a state management library seems to do exactly what you want.

Does swinject re instantiate the object?

I have a question, I'm using Swinject in a separate framework.
My app get the object from this framework and my appExtension use it too.
But in the Extension the Object is not correctly instantiate. Does Swinject use the first instance of my object or just recreate another one ?
thanks
I have found this in their documentation:
Graph (the default scope)
With ObjectScope.graph, an instance is always created, as in
ObjectScope.transient, if you directly call resolve method of a
container, but instances resolved in factory closures are shared
during the resolution of the root instance to construct the object
graph.
So, If you haven't specified the scope, that's the one that's applying in your case.
Complete documentation: https://github.com/Swinject/Swinject/blob/master/Documentation/ObjectScopes.md

Registering same concrete class with RegisterAutoWired and RegisterAutoWiredAs

My question is quite simple. I have to register all implementations by their interface and concrete types.
container.RegisterAutoWiredAs<AuthenticationManager, IAuthenticationManager>();
container.RegisterAutoWired<AuthenticationManager>();
I am using default singleton lifecycle. I want to make sure they resolve to same instance but my test shows I end up with two instances.
if (!ReferenceEquals(container.Resolve<IAuthenticationManager>(),
container.Resolve<AuthenticationManager>()))
{
throw new ApplicationException("multiple instances");
}
Is there way to use a single instance here?
Registering it twice causes a new instance for each type to be created, one for the interface and once for the concrete type.
If you want the same singleton instance you would first register an autowired instance and then just register against the other type resolving the same instance, e.g:
container.RegisterAutoWiredAs<AuthenticationManager, IAuthenticationManager>();
and either
container.Register(c => (AuthenticationManager)c.Resolve<IAuthenticationManager>());
or
var instance = (AuthenticationManager)container.Resolve<IAuthenticationManager>();
container.Register(instance);

Maintaining a single instance of a concrete class with unity

When using unity, if i attempt to inject a concrete type that i havent explicitly registered with the container, unity will attempt to locate the current type and will instantiate a new one for me, before injecting it into the class that depends upon it.
How can i ensure that only a single instance of this type is used? Do i need to explicitly register an instance with the container beforehand?
From MSDN:
You can use the Unity container to generate instances of any object that has a public constructor (in other words, objects that you can create using the new operator), without registering a mapping for that type with the container. When you call the Resolve method and specify the default instance of a type that is not registered, the container simply calls the constructor for that type and returns the result.
So simply put, yes, you have to register a mapping for your type to be able to use it as singleton in your app. You can achieve it using RegisterInstance method or RegisterType and providing the ContainerControlledLifetimeManager as the lifetime manager.

Castle Windsor Transient Lifestyle Not Activating

I'm having a problem with a component in my container with a Transient lifestyle. The first time I call resolve, I hit the constructor of the implementation type as expected.
However, the second time I call resolve, a new instance is not constructed. Rather, the existing instance is reused. I don't think this should happen, since my component's LifestyleType is set to Transient (I have verified this at runtime in debugging mode at a breakpoint):
Kernel.GetAssignableHandlers(typeof(object))[33].ComponentModel.LifestyleType
// 33 is the verified index of my component type...this returns Transient as expected
At the same breakpoint, I have run the following in the immediate window and verified that a new instance is not constructed:
Resolve(Kernel.GetAssignableHandlers(typeof(object))[33].Service)
// this does NOT return a new instance!
// ...It returns the same instance from the first time Resolve was called.
// I can tell by the state of the object and because the constructor on the object is not called.
Update:
I've narrowed the problem down, I think.
The below test fails:
var container = new WindsorContainer();
container.Kernel.AddComponent<MyLazyComponentLoader>(typeof (ILazyComponentLoader));
var instance1 = container.Resolve<MyClass>();
var instance2 = container.Resolve<MyClass>();
Assert.AreNotSame(instance1, instance2);
MyLazyComponentLoader simply returns
Component.For(service)
which is defaulting to Singleton LifestyleType (even though it shows up as Unknown on the ComponentModel. Is this by design?
Thanks.
Per Krzysztof Koźmic: Yes, the default lifestyle is singleton, Unknown means it's not specified explicitly, but Windsor treats it as if you specified Singleton. If you want it to be transient, be explicit.

Resources