3

There is web-api2 application. There is some custom attribute inside shared lib (web-api application refers this lib). Besides, this shared lib contains AppBuilderExtension (like app.UseMyCustomAttribute(new MySettings))

        public void Configuration(IAppBuilder app)
    {
        var httpConfiguration = new HttpConfiguration();

        ...
        app.UseWebApi(httpConfiguration);
        app.UseMyCustomAttribute(httpConfiguration, new MySettings() {Url = "https://tempuri.org"});
        ...
    }

The attribute needs injection of custom BL-service :

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
public class MyAttribute : FilterAttribute, IAuthenticationFilter
{
    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
      var myService = context.Request
            .GetDependencyScope()
            .GetService(typeof(IMyService)) as IMyService;
      await _myService.DoSomething();
    }

The question is: Is it possible to register IMyService right inside UseMyCustomAttribute() extension in my shared library? It's desirable not to refer any IoC libs (Autofac, Unity) in shared lib for this purpose. (In other words, don't require consumers of shared library to istantiate and inject IMyService each time they need MyAttribute) Something like:

    public static IAppBuilder UseMyCustomAttribute(this IAppBuilder app, HttpConfiguration config, MySettings settings)
    {
        config.Services.Add(typeof(IMyService), new MyService(settings.Url));
        return app;
    }

excception thrown

This method throws an exception. (As explained here Services is for predefined, well-known services.) How can I add MyService to applications service container, without using any DI/IoC libs (as Autofac, Unity and so on). What is the best solution to implement my UseMyCustomAttribute(...) method in my shared library?

UPDATED

My question is not about: "How to register dependency inside the attribute?" (answered here ) But, How to register dependency for library attribute? Is it possible to do it in library methods, such as owin .UseMyAttribute()? What should I do to register my custom IMyService for attribute, inside my UseMyCustomAttribute() method from above?

n.prokhorov
  • 930
  • 7
  • 13
  • Related to: https://stackoverflow.com/questions/4102138/how-to-use-dependency-injection-with-an-attribute – Steven Apr 14 '17 at 08:23
  • @Steven My question is not about: "How to register dependency inside the attribute?" (answered here ) But, How to register dependency for library attribute? Is it possible to do it in library methods, such as owin .UseMyAttribute()? What should I do to register my custom IMyService for attribute, inside my UseMyCustomAttribute() method from above? – n.prokhorov Apr 14 '17 at 13:33

1 Answers1

0

Is it possible to register IMyService right inside UseMyCustomAttribute() extension in my shared library?

Yes, this is possible, but you shouldn't. Each application should have only one Composition Root, and Composition Roots should typically not be reused. This means that shared libraries should not have any DI bootstrapping logic and should not have a dependency on the DI library.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • OK, so accordingly to this idea, the usage of OWIN DependencyResolver in any sahred library is also bad style? In this case, what is the correct solution for my case? Implement the instantiation of the plain old singletone of IMyService manually in my shared lib (near the attribute class)? P.S. could you please provide the example of how I "should not register IMyService right inside UseMyCustomAttribute() extension in my shared library", just as example of how it could be done. – n.prokhorov Apr 14 '17 at 16:14
  • @n.piskunov: You are currently using your `MyAttribute` as a Humble Object and resolve `IMyService` from the `DependencyScope`, which (as explained [here](https://stackoverflow.com/a/29916075/264697)) is fine if you have just a few of those attributes. This means that you should register your `MyService` inside your Composition Root (in your case probably the `Configuration` method). This should be all you have to do, or is there something I'm missing from your question? – Steven Apr 14 '17 at 16:57
  • Thank you for help. I've updated my question to explain my question in more clear way. My main question is - how to correctly register MyService in library method UseMyCustomAttribute(...). Some code example would be especially useful. – n.prokhorov Apr 17 '17 at 09:28
  • My answer doesn't change: don't register inside the extension method. – Steven Apr 17 '17 at 12:28