请注意,本站并不支持低于IE8的浏览器,为了获得最佳效果,请下载最新的浏览器,推荐下载 Chrome浏览器
欢迎光临。交流群:166852192

写一个Orchard Owin中间件


So you heard about how fancy Owin is, with all of its loosely-coupled thingies? Well, it's now in Orchard: as you may have heard on this week's Community Meeting, you can now write Owin Middlewares in the Orchard-y way. Let's see how!
We won't discuss how Owin works or what a middleware is, so if you don't know these yet, check out the linked meeting video. Also, make sure to grab the latest source from the 1.x branch of Orchard's repository because only the upcoming 1.9 version will have Owin support.
First you'll need to get familiar with the IOwinMiddlewareProvider interface. Middleware providers are injected services that return a collection of OwinMiddlewareRegistration objects. The latter ones contain the actual middlewares, i.e. those delegates that will run when the Owin pipeline is executed. This all is where the magic happens: you need to implement IOwinMiddlewareProvider and inside your implementation create OwinMiddlewareRegistration instances. See the following example:
所有你听说过Owin是怎么样的,所有的松散耦合的东西? 好吧,它现在在Orchard:你可能已经听说在本周的社区会议,你现在可以在Orchard写Owin Middlewares。 让我们看看如何!我们不会讨论Owin如何工作或中间件是什么,所以如果你还不知道这些,请查看链接的会议视频。 此外,确保从Orchard的存储库的1.x分支获取最新的源,因为只有即将到来的1.9版本将有Owin的支持。首先,你需要熟悉IOwinMiddlewareProvider接口。 中间件提供者是返回OwinMiddlewareRegistration对象的集合的注入服务。 后者包含实际的中间件,即在Owin流水线执行时运行的那些代理。 这一切都是魔法发生的地方:你需要实现IOwinMiddlewareProvider和你的实现创建OwinMiddlewareRegistration实例。 请参见以下示例:
public class OwinMiddleware : IOwinMiddlewareProvider
    {
        // Mostly you'll only need the WCA, see below why.
        private readonly IWorkContextAccessor _wca;
        // Or use Work<T> injections, also see below for the explanation.
        private readonly Work<ISiteService> _siteServiceWork;

        public ILogger Logger { get; set; }


        public OwinMiddleware(
            IWorkContextAccessor wca,
            Work<ISiteService> siteServiceWork)
        {
            _wca = wca;
            _siteServiceWork = siteServiceWork;

            Logger = NullLogger.Instance;
        }


        public IEnumerable<OwinMiddlewareRegistration> GetOwinMiddlewares()
        {
            return new[]
            {
                // Although we only construct a single OwinMiddlewareRegistration here, you could return multiple ones of course.
                new OwinMiddlewareRegistration
                {
                    // The priority value decides the order of OwinMiddlewareRegistrations. I.e. "0" will run before "10", but registrations
                    // without a priority value will run before the ones that have it set.
                    // Note that this priority notation is the same as the one for shape placement (so you can e.g. use ":before").
                    Priority = "50",

                    // This is the delegate that sets up middlewares.
                    Configure = app =>
                        // This delegate is the actual middleware.
                        // Make sure to add using Owin; otherwise you won't get why the following line won't compile.
                        // The context is the Owin context, something similar to HttpContext; the next delegate is the next middleware
                        // in the pipeline.
                        // Note that you could write multiple configuration steps here, not just this one.
                        app.Use(async (context, next) =>
                        {
                            // Note that although your IOwinMiddlewareProvider behaves like an ordinay Orchard dependency, the middleware
                            // delegate lives on its own and will run detached from the provider! Because of this you'll need to either
                            // access the Work Context as we do here, or inject your dependencies as Work<TDependency> objects. If you
                            // build multiple middlewares with many dependencies here, doing the following is a better choice.
                            var workContext = _wca.GetContext();

                            // But this would be an alternative:
                            var siteSettings = _siteServiceWork.Value.GetSiteSettings();

                            var clock = workContext.Resolve<IClock>();

                            var requestStart = clock.UtcNow;


                            // We let the next middleware run, but this is not mandatory: if this middleware would return a cached page
                            // for example then we could just leave this out.
                            await next.Invoke();
                            // Think twice when wrapping this call into a try-catch: here you'd catch all exceptions that would normally
                            // result in a 404 or an 503, so it's maybe better to always let them bubble up. But keep in mind that any
                            // uncaught exception here in your code will result in a YSOD.


                            var requestDuration = clock.UtcNow - requestStart;

                            // No need to use the ugly HttpContext, because we have OwinContext!
                            var url = context.Request.Uri;

                            // OK, but what if we _really_ need something from HttpContext?
                            if (context.Environment.ContainsKey("System.Web.HttpContextBase")) // This is Orchard, so should be true...
                            {
                                var httpContext = context.Environment["System.Web.HttpContextBase"] as System.Web.HttpContextBase;
                                if (httpContext != null)
                                {
                                    // Voilá, we have the ugly HttpContext again! Like RouteData:
                                    var routeDataValues = httpContext.Request.RequestContext.RouteData.Values;
                                    // ...you know what to do.
                                }
                            }

                            Logger.Information("The request to " + url + " on the site " + siteSettings.SiteName + " had taken " + requestDuration + "time.");

                            // You see, we've done something useful!
                        })
                }
            };
        }
    }
Oh, and you'll see inline documentation for all the Owin interfaces :-). Also this sample will be part of the Training Demo module.
Happy Owin'!
哦,你会看到所有Owin接口的内联文档:-)。 此样本也将作为培训演示模块的一部分。





作者原创内容不容易,如果觉得内容不错,请点击右侧“打赏”,赏俩给作者花花,也算是对作者付出的肯定,也可以鼓励作者原创更多更好内容。
更多详情欢迎到QQ群 166852192 交流。