Skip to content
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

Enable OnlyIf handling for decorators and modules #1235

Closed
tillig opened this issue Dec 4, 2020 · 5 comments
Closed

Enable OnlyIf handling for decorators and modules #1235

tillig opened this issue Dec 4, 2020 · 5 comments

Comments

@tillig
Copy link
Member

tillig commented Dec 4, 2020

Problem Statement

There is not currently an easy way to conditionally register decorators or modules using the OnlyIf() style syntax. You can register types conditionally...

builder.RegisterType<X>()
       .OnlyIf(b => b.IsRegistered(new TypedService(typeof(Y))));

...but you can't do that for decorators or modules. RegisterDecorator<T, U>() is a void method. While it offers the ability to conditionally apply the decorator, if you don't want the perf hit of executing the condition function on every resolve there's no easy way to conditionally register.

ContainerBuilder.RegisterModule<T>() is similar - it has a special IModuleRegistrar that gets returned, but that only allows chained module registrations and not conditions.

This issue is based on the StackOverflow question here.

Desired Solution

It would be nice to have OnlyIf support in the cases where we don't currently have it. This may require changing RegisterDecorator<T, U>() to return a new IDecoratorRegistrar or something similar such that it can add a chained callback for OnlyIf(). For modules, it's a new extension on that IModuleRegistrar.

Alternatives You've Considered

  • Make DecoratorMiddleware public: While this would potentially solve the issue in the StackOverflow question (conditional registration of a decorator), it would still mean the entire contents of RegisterDecorator would be copy/pasted into another codebase and have to be managed there. If we change the set of things in Autofac that are required to make a decorator work, the external user's code would break unexpectedly.
  • ... that's about it. That wouldn't solve it for modules, either.

Additional Context

Changing RegisterDecorator<T, U> to return a type instead of void is a breaking API change (I think... pretty sure) because the method signature changes. Transitive dependencies (my code => some other code that's compiled and registers decorators => Autofac) might break because it couldn't find the void version of RegisterDecorator. I'd have to test that, but... pretty sure. If so, that'd be a 7.x release and we might want to consider a new method/overload to handle that if we don't want to release the breaking change so soon after 6.0.

@ModernRonin
Copy link

@tillig
Copy link
Member Author

tillig commented Apr 12, 2021

@ModernRonin No, that's a different thing. While it may affect the return type or handling of RegisterDecorator<T, U>, it hasn't got anything to do with enabling OnlyIf so it'd be a different issue.

@ModernRonin
Copy link

I just saw your comment on the SO question - that's a very good point, thank you :-)

@tillig
Copy link
Member Author

tillig commented Oct 8, 2021

OnlyIf for modules will be out in 6.3.0 shortly.

@tillig
Copy link
Member Author

tillig commented Sep 1, 2023

Looks like we forgot to close this one. Fixed in #1272.

@tillig tillig closed this as completed Sep 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants