Я вижу тревожную тенденцию в vNext и нуждаюсь в некотором назидании, потому что Im не видит большую картину того, где мы принимаем сообщество. Почему vNext отказался от базовых парадигм ООП, таких как интерфейсы, вместо того, что я могу описать только как "программирование на основе условных обозначений"?
Возможно, мне просто не повезло, и типы классов, с которых я начал, - это разовые единороги, но в течение коротких трех дней, когда я работал с vNext, я сталкивался с двумя классами, которые, похоже, отказались от базовых программных конструкций, которые меня озадачили.
Первый - это класс промежуточного программного обеспечения. Средство промежуточного уровня в vNext предназначено для работы без реализации какого-либо интерфейса или наследования из какого-либо общего базового класса, но магически вызывается в конвейере vNext с помощью метода Invoke
. Когда мы решили, что интерфейсные контракты бессмысленны? Это просто не имеет для меня никакого смысла. Если есть третья сторона, которая собирается позвонить в мое промежуточное ПО, тогда должен быть контракт, в котором говорится, что я собираюсь реализовать 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!");
}
}
Второй - это веб-приложение, которое самостоятельно размещается в консольном приложении. Когда вы пытаетесь запустить команду для запуска самостоятельного хостинга (dnx . web
) только во время выполнения, вы получаете ошибку, которую забыли магический класс Startup
. Опять же, потому что мне не хватает терминологии, и я могу описать это только как "основанное на соглашениях программирование". В OWIN
мы, по крайней мере, имели OwinStartupAttribute
, которые могли быть применены на уровне сборки. Теперь мы остались, ну ничего.. Ничто в моем коде не указывает, что я намерен определить класс запуска, который может быть вызван сторонней программой.
System.InvalidOperationException: тип с именем "StartupDevelopment" или "Запуск" не удалось найти в сборке "ConsoleApp1".
Угадайте, что происходит, когда вы следуете "подсказке" из приведенного выше исключения?
System.InvalidOperationException: метод, названный 'ConfigureDevelopment' или 'Configure' в типе "ConsoleApp1.Startup" не найден.
Программирование неудачей, да, детка! Нет проблем, это будет только четверть моей оценки того, сколько времени потребуется, чтобы отправить это приложение. О, и можете ли вы угадать, какой интерфейс реализует класс 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, проверка времени компиляции винтов, винтовая визуальная студия и ее передовая интеллисенса, пусть они едят документацию".
Пожалуйста, назидайте меня на это безумие...