在启动 Owin 中注入服务

3

我有一个实现洋葱架构的新应用程序���现在我想在owin的启动类中注入一个服务。因为它位于引导程序项目中,该引导程序项目首先使用webactivator运行,所以ioc过程在命中启动类之前就已经启动了。是否可以在启动类中注入服务?

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();

        // Web API routes
        config.MapHttpAttributeRoutes();

        ConfigureOAuth(app);

        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        app.UseWebApi(config);
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        // i want to use an injected service inside a provider :my problem :(  
        var providers = Providers(service);

        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            //For Dev enviroment only (on production should be AllowInsecureHttp = false)
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/generateToken"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
            Provider = providers,
            AccessTokenFormat = new CustomJwtFormat("http://localhost:18292/")
        };

        // OAuth 2.0 Bearer Access Token Generation
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
    }
}

为什么不将提供者和/或服务传递到 ConfigureOAuth 方法中?这样就会颠倒控制权。您需要一个入口来设置IOC容器,因此最好是在 StartUp 中进行设置。顺便说一下,您不必遵循 StartUp 约定。如果愿意的话,您可以手动启动owin应用程序。 - Meirion Hughes
谢谢你的评论,但是如果我在configureOAuth中传递service和/或provider,我应该首先在Configuration方法中传递它,因为它是调用者。问题是我不能使用Configuration(IAppbuilder, service ),因为它会抛出异常(Startup没有预期的签名'void Configuration(IAppBuilder)')。 - moyomeh
是的,你说得对。我会向你展示我如何做到这一点。 - Meirion Hughes
1个回答

2
您不必使用“StartUp”约定,在这种情况下,完全控制应用程序构建流程可能更好。这并没有直接回答您的问题,而是对如何实现的延伸评论;具体来说,手动设置“AppBuilder”并将应用程序发送到Owin服务器。
顺便说一下,我在这里使用nowin来创建实际的服务器。我相信其他人会用Asp.Net的方式回答这个问题。
using AppFunc = Func<IDictionary<string, object>, Task>;

public class App
{
    private IAppBuilder _appBuilder;
    private HttpConfiguration _config;
    private ISomeServiceProvider _provider;

    public App(IAppBuilder appBuilder, ISomeServiceProvider provider, HttpConfiguration config)
    {
        _appBuilder = appBuilder;
        _provider = provider;
        _config = config;

        ConfigureOAuth(_appBuilder, provider);

        _appBuilder.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        _appBuilder.UseWebApi(config);

        //Build Owin App
        _owinApp = (AppFunc) _appBuilder.Build(typeof (AppFunc));


    }

    void ConfigureOAuth(IAppBuilder app)
    {
        //...
    }

    public void Start()
    {
        //Make an endpoint
        var owinEndpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 8080);

        //Build WebServer (Nowin)
        var owinServer = ServerBuilder.New()
            .SetOwinApp(_owinApp)
            .SetEndPoint(owinEndpoint)
            .Build();

        // Start WebServer
        using (owinServer)
        {
            owinServer.Start();

            Console.WriteLine("Press ENTER to stop");
            Console.ReadLine();
        }
    }
}

现在,在引导程序/启动阶段将应用程序添加到容器中,解析它并运行它。

public class Program
{
    public static void Main(string[] args)
    {
        var container = GetIoC();

        container.Bind<App>().ToSelf();
        container.Bind<IAppBuilder>().To(()=>new AppBuilder());
        container.Bind<HttpConfiguration>();
        // ... other bindings you need 

        //resolve root
        var app = container.Get<App>();

        app.Start(); 
    }
}

记住这是类似于伪代码的代码,但你可以大致了解其思想。

这是一个不错的开始,但我在思考 container.Get<ISomeServiceProvider>(); 是否是一种反模式。在我的情况下,容器是在其他项目中定义的,所以如果我采用这个解决方案,最好使用 GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IService<XXXX>)),但我对它不太确定。 - moyomeh
@mmansouri 更新为具有根并将所有内容注入到全包含的“App”中。 - Meirion Hughes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接