Share castle windsor singleton instance across multiple components - inversion-of-control

I want to be able to do this:
<component id="Component1" service="Foo.IFoo, Foo" type="Foo.Bar, Foo" lifestyle="singleton" />
<component id="Component2" service="Foo.IFoo, Foo" type="Foo.Bar, Foo" lifestyle="singleton" />
Such that when I do this:
IFoo foo = m_container.Resolve<IFoo>("Component1");
Or this:
IFoo foo = m_container.Resolve<IFoo>("Component2");
..I get the same singleton instance, not a seperate instance per component.
Is this possible?
Thanks.

If all you have is the interface "Name" at runtime how are you planning to call the generic Resolve<> method on the windsor container? If you truely only want one singleton instance of IFoo regardless of the comopnent "Name" then just register one as a singleton and call:
IFoo foo = m_container.Resolve<IFoo>();
If you are looking to have multiple interfaces return the same component you can look at using Forward types.

Related

Resolving to parent interface during constructor injection

This involves autofac and c#. I have an interface derived from a parent interface:
public interface IJ4JLogger<out TCalling>
{
}
public interface IJ4JSmsLogger<out TCalling> : IJ4JLogger<TCalling>
{
}
Certain classes depend on being supplied an instance of the parent interface during construction:
public FileHistoryConfiguration( IJ4JLogger<FileHistoryConfiguration> histLogger, IJ4JLogger<FileHistoryService> svcLogger )
{
}
But if I register the type like this with autofac:
builder.RegisterGeneric( typeof(J4JSmsLogger<>) )
.As(typeof(IJ4JSmsLogger<>))
.SingleInstance();
where J4JSmsLogger<> is a class implementing IJ4JSmsLogger<>, then this call fails with an error that it can't find anything registered to provide an IJ4JLogger<> interface:
_fhConfig = _svcProvider.GetRequiredService<IFileHistoryConfiguration>();
I can work around the problem by changing the As<> clause in the registration of J4JSmsLogger<> to treat it as a IJ4JLogger<> instance, and then cast the result of resolving that interface to IJ4JSmsLogger<> whenever I need the extra capabilities of the child interface.
But I don't understand why I have to do that. Is there an additional step I need to take during registration of the types with autofac so that objects implementing the child interface will satisfy a need for the parent interface?
Cleaner Workaround
Reading more about autofac I learned something new: you can define as many As<>() clauses (including AsSelf()) as you want. So changing my autofac configuration to:
builder.RegisterGeneric( typeof(J4JSmsLogger<>) )
.As(typeof(IJ4JSmsLogger<>))
.As(typeof(IJ4JLogger<>))
.SingleInstance();
provides a cleaner solution than constantly casting resolved instances.
I'm not going to submit it as an answer, though, because I am curious why autofac doesn't do this kind of downcasting automatically, and whether any other DI frameworks do.
Autofac won't cast to base types for you like that. It generally assumes wiring is exact. You could run into some real problems if it didn't, like if someone has a constructor like...
public class BadTimes
{
public BadTimes(object input) { }
}
Which object does it put in there? Everything casts down to object.
However, you could always register it as both types and call it a day:
builder.RegisterGeneric(typeof(J4JSmsLogger<>))
.As(typeof(IJ4JSmsLogger<>))
.As(typeof(IJ4JLogger<>))
.SingleInstance();

Why Dagger Component requires #Scope annotation

When you want to provide scoped dependency, Dagger requires to annotate Component with this Scope too. What is the reason for that?
#Singleton // <- for what?
#Component(modules = [MyModule::class])
interface MyComponent {
//...
}
#Module
interface MyModule {
#Binds
#Singleton
fun provideDependency(impl: DepImpl): Dep
}
Scoping in Dagger means "give this binding the same lifetime as the component that contains it", so the component itself holds onto the instance so it can provide the same instance repeatedly.
Components are also hierarchical: through subcomponents and component dependencies you can have multiple components coexisting in the same application. In a typical Android app, you might have an Application component that provides bindings for several Activity components, and and each of those Activity components provides bindings for several Fragment components.
Though Dagger could theoretically infer scopes based on which module installs it, instead of requiring you to specify which scope applies to which component, this makes it more difficult to work with classes that declare scope and #Inject annotations without an explicit Dagger binding. If you're in an Activity component that inherits bindings from an Application component (often "singleton"), and an Activity binding relies on an #ApplicationScope-annotated class with an #Inject constructor, how would Dagger know to put it in the Application component instead of the Activity component? This might also make your code harder for humans to understand—I know I'd have trouble following it.

GWT generate-with and replace-with mix

I encounter a strange issue today, with the generate-with and replace-with options in my gwt.xml file. I explain :
First of all, I have two classes "A" and "B" and an interface named "I", with "B extends A implements I". I also have a "IGenerator" generator
In my gwt.xml, I have something like this :
<generate-with class = "IGenerator" >
<when-type-assignable class = "I" />
</generate-with>
<replace-with class = "B">
<when-type-is class = "A">
</replace-with>
The problems is that my object A should be a B_Generated object.
I have to say that the when B doesn't extend A, it works and when B doesn't implement I, it works to... But in this case, it doesn't work.
Hope you could help me for this stuff...
Thanks you all before.
-- MORE INFORMATION --
In my project :
A : PlaceManager
B : Project1_PlaceManager
C : Project2_PlaceManager
I : AnnotatedClass -- means that the class contains some annotations that must be replaced by code snippets --
My PlaceManager does all the work for managing places, activities and stuff like this.
B and C PlaceManager have their own Places that are declared by annotations like :
#Place
MyPlaceA placeA; // this part is replaced by a creation snippet
#Place
MyPlaceB placeB; // this part is replaced by a creation snippet
So the thing is that running one or another project, the PlaceManager must be replaced by the good one, and the new class must be generated to replace my snippets.
NB : This description is very simple and the projects much more complex...
There's no chaining of deferred-binding rules: the first rule that matches is used, and the result is not evaluated against the rules. That means you cannot say that GWT.create(A.class) would run your IGenerator that expects a class implementing I, that A doesn't implement.
You'd have to either create an AFactory (that would simply do a new A() by default) that you could replace with a BFactory (that would do a GWT.create(B.class), triggering your IGenerator) and change your code to use that indirection; or create a generator that can match A and call into your IGenerator with B as input (instead of the received A).
That said, I think you're (kind of) abusing deferred-binding, and should rather use some kind of dependency injection (that could bind a GWT.create(B.class) when an A is expected).
I might be wrong but from what I know and being using you choose either to use a generator or use replacement but not both for the same class. I do not really see the point.
Why generating a class for it to be replaced by another ?
http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsDeferred.html

Notify parent context object about child context object creation

this is a situation I would like to implement.
public class ComponentRepository
{
public void Register(IComponent component)
{
// store component in collection
}
}
<!-- root context -->
<object id="Repository" type="NameSpace.ComponentRepository" />
<!-- child context (0 - n contexts) -->
<object id="Component" type="NameSpace.Component"/>
I would like to register all IComponent objects with ComponentRepository. I suppose it can be done with some kind of publish/subscribe mechanism, but I would like to keep my classes clean (without implementing any of spring.net interfaces).
What is the best way to achieve this?
I understood your question as this:
After the instantiation of the child-context's Component, the Register-method of a ComponentRepository defined in another context should be called.
As far as I know, there is no xml-declarative way to achieve what you want.
I would suggest to either make your ComponentRepository IApplicationContextAware (which is what you explicitly don't want) or to create a new IApplicationContextAware Class which takes a dependency of ComponentRepository.
That way you can call the ApplicationContext's GetObjectsOfType Method and retrieve all IComponent objects to pass to the ComponentRepository.

StructureMap IoC problem getting the instance in runtime

i have 2 concrete types "CategoryFilter" & "StopWordsFilter" that implements
"IWordTokensFilter".
Below is my setup:
ForRequestedType<IWordTokensFilter>().TheDefaultIsConcreteType<CategoryFilter>()
.AddInstances(x =>
{
x.OfConcreteType<StopWordsFilter>();
}
);
The problem is the run-time when structure map auto inject it on my class, bec. i have arguments with same plugin-type:
public ClassA(IWordTokensFilter stopWordsFilter, IWordTokensFilter categoryFilter)
i'm always getting CategoryFilter in my first argument but it should be stopWordsFilter.
How can i setup this in a right way? thanks in advance
There are a number of possible solutions:
1) Does ClassA need to differentiate between the filters, or does it just need to run them both? If not, you can change the constructor to accept an array, which will cause all registered instances of IWordTokensFilter to be injected:
public ClassA(IWordTokensFilter[] filters)
You can then foreach over the filters to apply them.
2) If you do need to differentiate them, because they need to be used differently, you may consider having one implement a marker interface the better describes its purpose. ClassA could then be changed to take in an IWordTokensFilter and an ICategoryFilter (or whatever you name the marker interface). Register CategoryFilter with ICategoryFilter and then both will be injected properly.
public ClassA(IWordTokensFilter stopWordsFilter, ICategoryFilter categoryFilter)
3) You can tell StructureMap explicitly how to create ClassA:
ForRequestedType<ClassA>().TheDefault.Is.ConstructedBy(c => {
return new ClassA(c.GetInstance<StopWordsFilter>(), c.GetInstance<CategoryFilter>());
});
4) You can tell StructureMap to override one of the dependencies for ClassA:
x.ForRequestedType<ClassA>().TheDefault.Is.OfConcreteType<ClassA>()
.CtorDependency<IWordTokensFilter>("stopWordsFilter").Is<StopWordsFilter>();