Creating registrations dependent on current ComponentRegistry - Autofac - autofac

Currently stuck on a problem with autofac registrations. To summarise I have an autofac module that registers many instances of IHandle. There could be many implementations of IHandle and IHandle and each typeof(A) or typeof(B) has a corrosponding configuration class that is passed into another Module with the same builder.
My question is DURING the build process how can I get the current registrations that implement > and match them to the correct message configuration, remembering that there could be many implementations of IHandle.
I want to use builder.Register(ctx => {}) but how can I loop within this Register call and register multiple processors for each handler in the component registry
I can get the types of IHandle within the registery by dont know how to register the new processor matching the configuration
Hope that makes sense....
Thanks in advance
Richard

Related

How to resolve Autofac per-request service from custom attribute

I have configured my EF context configured like so
b.RegisterAssemblyTypes(webAssembly, coreAssembly)
.Where(t => t.IsAssignableTo<DbContext>())
.InstancePerLifetimeScope();
I would like to use it from a custom authorization attribute that hits the database using my EF context. This means no constructor-injection. I achieve this by using CommonSeviceLocator
var csl = new AutofacServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => csl);
...
var user = await ServiceLocator.Current
.GetInstance<SiteContext>().FindAsync(id);
I am finding that this fails with a "multiple connections not supported" error if the browser issues two simultaneous requests to routes using this attribute. It seems like this might be due to what is mentioned in this answer. My guess is that ServiceLocator resolves from the root scope rather than the web request scope and the two request are conflicting (either request in isolation works fine).
This seems confirmed by that when I change to InstancePerRequest() I get this from any invocation of the attribute.
Autofac.Core.DependencyResolutionException No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is
being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
So it seems like maybe ServiceLocator is simply not the way to go.
How do I resolve the request-scoped SiteContext from inside the attribute (using a service-locator pattern)?
Your issue derives from the fact that you are trying to put behavior inside of an Attribute. Attributes are for defining meta-data on code elements and assemblies, not for behavior.
Microsoft's marketing of Action Filter Attributes has led people implementing DI down the wrong path by putting both the Filter and the Attribute into the same class. As described in the post passive attributes, the solution is to break apart filter attributes into 2 classes:
An attribute that contains no behavior to mark code elements with meta-data.
A globally-registered filter that scans for the attribute and executes the desired behavior if present.
See the following for more examples:
Constructor Dependency Injection WebApi Attributes
Unity Inject dependencies into MVC filter class with parameters
Implementing passive attributes with dependencies that should be resolved by a DI container
Dependency Injection in Attributes: don’t do it!
Injecting dependencies into ASP.NET MVC 3 action filters. What's wrong with this approach?
How can I test for the presence of an Action Filter with constructor arguments?
Another option is to use IFilterProvider to resolve the filters as in IFilterProvider and separation of concerns.
Once you get your head around the fact that Attributes should not be doing anything themselves, using them with DI is rather straightforward.

How to Install a module that needs an instance per something else that is registered in Castle Windsor

I am trying to get the hang of IoC and DI and am using Castle Windsor. I have an object I have created that can be multiply instantiated but over different generic types. For example
MyType<Generic, Generic2>
on Installation of MyType's assembly
container.Register(Component.For(typeof (IMyType<>)).ImplementedBy(typeof (MyType<>)));
Then in my main modules initialization I install MyTypes module with MyTypeInstaller which is a IWindsorInstaller.
Then I am manually resolving the various types of MyType that I want (this will actually be spread around different installers). But something like
container.Resolve<IMyType<type1, type2>();
That creates an actual instance of MyType registered for the generic types passed in.
This works fine, I get the instances of MyType<,> I need created.
Now, finally I have another module I have created that I will install last. I want to say,
container.ResolveAll<IMyType<,>>()
then create this instances of this new object for each object that exists.
However I cant seem to resolve all of the IMyTypes<,> without knowing the concrete types that each one were instantiated as.
At any rate, it is possible I am just doing this wrong and want feedback in general as well.
First, if MyType<T1,T2> can only be instantiated once for each combination of T1,T2 then you should be registering it is a Singleton.
Second, You cannot call strongly type container methods (like ResolveAll<T>) with an open generic - it MUST be a closed type.
Third, MyType is an open generic type and the number of closed generic classes is infinite (generic type constraints are not considered by the container). So, as far as the container is concerned you can call Resolve<ANYTHING, ANYTHINGELSE> and it will attempt to provide a MyType<ANYTHING,ANYTHINGELSE> for you. If ANYTHING and ANYTHINGELSE don't satisfy the type constraints then you will simply get a run time error.
Even if you could call ResolveAll<IMyType<,>>() what would you expect it to return given that you have registered an open generic implementation?

ELKI: Implementing a custom ResultHandler

I need to implement a custom ResultHandler but I am confused about how to actually integrate my custom class into the software package.
I have read this: http://elki.dbs.ifi.lmu.de/wiki/HowTo/InvokingELKIFromJava but my question is how are you meant to implement a custom result handler such that it shows up in the GUI?
The only way I can think of doing it is by extracting the elki.jar package and manually inserting my custom class into the source code, and then re-jarring the package. However I am fairly sure this is not the way it is meant to be done.
Also, in my resulthandler I need to output all the rows to a single text file with the cluster that each row belongs to displayed. How tips on how I can achieve this?
There are two questions in here.
in order to make your class instantiable by the UIs (both MiniGUI and command line), the classes must implement our Parameterization API. There are essentially two choices to make your class instantiable:
Add a public constructor without parameters (the UI won't know how to set your parameters!)
Add an inner static class Parameterizer that handles parameterization
in order to add your class to autocompletion (dropdown menu), the classes must be discovered by the MiniGUI/CLI/other UIs. ELKI uses two methods of discovery:
for .jar files, it reads the META-INF/elki/interfacename service files. This is a classic service-loader approach; except that we also allow ordering instances.
for directories only, ELKI will also scan for all .class files, and inspect them. This is mostly meant for development time, to avoid having to update the service files all the time. For performance reasons, we do not inspect the contents of .jar files; these are expected to use service files.
You do not need your class to be in the dropdown menu - you can always type the full class name. If this does not work, adding the name to the service file will not help either, but ELKI can either not find the class at all, or cannot instantiate it.
There is also a tutorial on implementing a custom result handler, but it does not discuss how to add it to the menu. In "development mode" - when having a folder with .class files - it will show up automatically.

Are PlayPlugin instances shared between different threads (Play 1.2.5)

I'm trying to find out how PlayPlugin objects are used within Play Framework (1.2.5).
Are same PlayPlugin instances shared between different Play threads?
With some source lookup I suppose yes but since Play has some meta-programming in many places and I'm not so familiar with all this, I'm not 100% sure.
Call stack for PlayPlugin.beforeInvocation:
PlayPlugin.beforeInvocation
PluginCollection.beforeInvocation
list of enabled plugins is a field within PluginCollection)
Invocation.before
uses static field Play.PluginCollection
Thread.currentThread().setContextClassLoader(Play.classloader) is one thing that could possibly affect Play.PluginCollection, for example.
Single instance for all threads -behaviour would also be confirmed by the article Play Framework: Introduction to Writing Modules:
beforeActionInvocation(): This code is executed before controller
invocation. Useful for validation, where it is used by Play as well.
You could also possibly put additional objects into the render
arguments here. Several plugins also set up some variables inside
thread locals to make sure they are thread safe.
So, I suppose the answer is that yes, the instances are shared, but would like to confirm that.
You are right. Each instance of PlayPlugin(subclass of course) is shared throughout the entire JVM. You get that instance via Play.plugin(class<T> clazz) method call.

Does GWT deferred binding return singletons of the same type within the scope of a single EntryPoint?

Let's say I have a number of GWT modules which are used as libraries, and one module with an entry point which inherits all of the library modules.
Each of the submodules needs to access a single instance of SomeClass.
If I call GWT.create(SomeClass.class) in modules A & B, do I get the same instance? If so, is this guaranteed?
No. GWT.create(SomeClass.class) compiles to new SomeClass(), unless there is a rebind rule of some kind - a replace-with or a generate-with rule will cause this to instead invoke the default constructor of whatever type is selected by those rules.
This means that GWT.create is not a suitable way to provide access to a singleton instance. Instead, consider some DI tool like Gin, or manual DI by always passing around the same instance. It is also possible to use the static keyword to keep a single instance where all code compiled into the same app can reference it.