-
-
Notifications
You must be signed in to change notification settings - Fork 837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditionally registering decorators #727
Comments
Glad you are interested in enhancing support for this! My most complex AutoFac code is around proper decorator support. I ended up iterating through all my types to do the decorator registration. Here is an example issue. I create attribute, When it comes time to register, I want to do the following:
Or I might use an interface. If I add the IUnitOfWork interface to a Command, then I want the command handler for that Command to be decorated only if the Command implements that interface. And so on...What I did was
It is a bunch of manual code. I am not sure how you would provide support for this. But, essentially I would want to see something like this:
The
The way decorators are applied now is a bit messy. You have to create a key for each level and then use that key for the next level....but you have to know in advance if there is a next level so you can not key it...or it will not work. Note in the code above, the need for the ability to just add a decorator without worrying about if it is the last decorator in the chain...or what the prior decorator was. Another optional api...perhaps you register it like you do today...then the decorator is applied like:
With this you can register decorators on top of whatever decorator was there for everything that was originally registered as Note |
Reviewed my implementation in detail again. One of the biggest reasons I cannot make my custom registration code better is around the decorator keys. If I could register the main handler for the query...not knowing if it will be decorated or not. This would make a big difference. |
Looking around, simple injector does exactly what is needed.
|
Is there anyway in the current autofac, to register the open generic without a 'keyed registration', then when I want to decorate it - locate all those unkeyed registrations - key them, then register the decorator to that key. Then, if I wanted to decorate that decorator, I would again get all the 'unkeyed registrations' and key them, etc. That would be huge. (Just trying to find a solution that works with the current architecture) |
I wonder if you could use resolved parameters to customise the decorated parameter to the decorator. http://docs.autofac.org/en/latest/faq/select-by-context.html#option-4-use-metadata You could inspect the generic parameter of the type being decorated to see if it implemented a particular interface or whatever and provide a special service to handle that or another one if it didn't. |
No need to do that - pretty complex and runtime decision making. Basically I just do my own reflection to workout all the types and relationships so I can decorate giving the autofac constraints. So, this can be done - but just not with the existing autofac api. |
Yeah that would probably be easier on the brain :) |
@alexmg Any update on this now that DNX has settled down? |
So @waynebrantley I've just come back to this :) Using your reflection solution are you stuck having to create a unique stack for every possible combination of decorators? Say you had IFoo, IBar and IMoo and each of those interfaces had a corresponding decorator to do something would you have to create a decorator stack for foo, bar and moo. then foo + bar, foo + moo, bar + moo, foo + bar + moo etc? 🐙 |
@worldspawn Yes..you are! It is due to the way they wire up the decorators. Hoping for a better solution from them...dont really want to switch DI as that is a big pain. |
Yeah that's pretty god awful. It looks like this could be done by writing an IRegistrationSource. (http://docs.autofac.org/en/latest/advanced/registration-sources.html) I've been browsing the current implementation and it is using ParameterResolvers. However its a pretty serious learning curve. The code is so heavily abstracted its extremely hard to see whats going on. Its going be one of those trial and error code sessions :D I ran into a wall pretty quickly where the current code gets the implementing type of the service type by reading the registrations (or something). Its all internal so I cant use it. An extension method that accepted a list of decorator types and optionally a predicate (per type) and the base open generic type that is being decorated is what I'd like to see. I think it needs to be a single call because the paramter resolver will need to do something like check if the decorator is allowed and if not move on to the next decorator and inject that instead. |
Having to name decorated objects in Autofac is in my opinion its greatest shortcoming. It messes with proper modularization of the registration code and prevents easy testing of partial container setups. It would be absolutely wonderful to have a proper decorator API, where we could register objects without caring about whether those objects will later be decorated. The same goes for decorators themselves, their registration should not depend on whether further decorators will be applied. |
We're pushing to enhance decorator syntax and features, which will hopefully resolve this issue. I've created a larger meta-issue for tracking that at #880. In the meantime, I'll close this specific issue and hopefully we can handle everything at once. |
From [email protected] on Google Group:
https://groups.google.com/forum/#!topic/autofac/svtRInh0my4
Originally, you helped me out with getting all the decorators attached using open generics here. https://groups.google.com/forum/#!searchin/autofac/brantley/autofac/lV2X4hR0mak/F5g4MfhUR08J
That has been working great and I modified the code so you could pass in a list of decorators to apply (decorators decorating decorators). For completeness here is that code (in case someone wants it):
Anyway, the big issue at hand is conditionally registering decorators. This is a shortcoming I have been working around for a while and last April you said may focus on it after DNX settle down (https://groups.google.com/forum/#!searchin/autofac/decorator/autofac/vSU6kx7XX2M/AxhpHqddGzkJ)
However, I now have a really wild situation that I cannot resolve.
This seems to work great. I open my web application and sure enough the new registration is being applied and there are no issues.
The issue is that if I do a WEBAPI request - it continues to use the original registration and not the new one!! I have pulled my hair out on this issue.
Any ideas?
The text was updated successfully, but these errors were encountered: