也许我只是不幸运,我开始的类型是一次性的独角兽,但在短短的三天我一直在使用vNext我遇到了两个类,似乎已经放弃了基本的编程结构,让我神秘。
第一个是中间件类。 vNext中的中间件被设计为在不实现任何接口的情况下工作,也不继承任何公共基类,但通过Invoke方法在vNext管道中神奇地被调用。我们什么时候决定接口合同是毫无意义的?这对我来说根本没有意义。如果有第三方将要调用到我的中间件,那么应该有一个合同,声明我要实现XX。它表达意图,并提供编译时检查。没有合同,没有什么阻止所述第三方完全改变它期望的方法的签名,并且只有在运行时你知道一些东西出了问题。更不用说穷人,我和我的亲戚,盯着代码无法解释应该实现什么以及让我从A点到B点的生命周期事件的序列。
public class SampleMiddleware // complete lack of interface implementation or base class inheritance { private readonly RequestDelegate _next; public SampleMiddleware(RequestDelegate next) { _next = next; } // yet a magical method that somehow gets invoked in a pipeline.. wth.. public async Task Invoke(HttpContext context) { context.Response.ContentType = "text/html"; await context.Response.WriteAsync("SampleMidlleware fired!"); } }
第二个是在控制台应用程序中自承载的Web应用程序。当您尝试运行命令以仅在运行时启动自承载(dnx。web)时,您会收到错误,忘记了一个神奇的启动类。再次因为我缺乏术语,我只能将其描述为“基于约定的编程”。在OWIN中,我们至少有OwingStartupAttribute可以在组件级应用。现在我们离开了,没有什么。我的代码中没有说明我的意图是定义一个可以被第三方程序调用的启动类。
System.InvalidOperationException: A type named ‘StartupDevelopment’ or
‘Startup’ could not be found in assembly ‘ConsoleApp1’.
猜测当你遵循上面的例外的“提示”会发生什么?
System.InvalidOperationException: A method named
‘ConfigureDevelopment’ or ‘Configure’ in the type
‘ConsoleApp1.Startup’ could not be found.
编程失败,是宝贝!没有问题,这只会使我估计需要多长时间才能得到这个应用程序发货..哦,你能猜到Startup类实现什么接口?没错,没有,纳达,拉链。你闻到了吗?我闻到烟雾..
ConsoleApp1
public class Program { public void Main(string[] args) { var config = new Configuration() .AddJsonFile("config.json") .AddCommandLine(args); Console.WriteLine(config.Get("message")); foreach (var arg in args) { Console.WriteLine(arg); } Console.ReadLine(); } }
Startup.cs
public class Startup { public IConfiguration Configuration { get; set; } public Startup(IHostingEnvironment env) { // Setup configuration sources. Configuration = new Configuration() .AddJsonFile("config.json") .AddEnvironmentVariables(); } }
project.json
"commands": { "ConsoleApp1": "ConsoleApp1","web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000/" }
任何你的“老计时器”召回global.asax和其使用基于会议的应用程序事件? Application_Error(object send,EventArgs e)你闻到了吗?谁想通过文章和文档穷人,因为他们不记得“公约”?这就像他们宣称,“螺丝OOP,螺旋编译时检查,螺丝Visual Studio和其高级智能,让他们吃文档。
请教我这个疯狂…
解决方法
启动
例如,“web” command allows you to specify your startup assembly在命令行使用–app或从a default Microsoft.AspNet.Hosting.ini config file使用主机:应用程序。事实上,你不必构建你自己的WebHostBuilder是由于基于约定的编程,但你肯定可以从你自己的Program.cs开始,并建立自己,如果你喜欢。
中间件
中间件类是yet another example of method-level injection – 许多参数可以直接从应用程序的IServiceProvider添加。我不认为我可以添加任何有用的东西Tugberk在博客中说:这是一个很好的阅读。
控制器/操作
我知道你没有问关于控制器,但在控制器中的操作是类似的;你不会在任何流行的MVC框架中找到一个接口。相反,这些参数是在使用模型绑定时依赖注入的。目前,MVC6团队允许一个[FromServices]装饰通过Model Binding注入请求级依赖,但我听说他们正在考虑删除它。我希望他们设置注入更直接从服务提供商,以便我们可以在我们自己的框架中使用它。
其他想法
我真诚地希望有一个好的方法来引用一个“方法组”(因为编译器调用它),而不知道参数,以便我们可以做更多的方法级依赖注入和较少遵守特定的接口,我自己。我也希望有一个好的方法来声明一个接口,它有一个方法,谁在乎什么是参数。
public interface IMiddleware { // No Syntax for this Task Invoke(... any); } // No Syntax for this either,unless you know in advance what the parameters will be await serviceProvider.InjectAndInvoke(middleware.Invoke);
如果C#添加到规范,那么我们肯定可以有你正在寻找的接口。