Why is ASP.NET Core's Startup class not an interface or abstract class?
This is in regards to the design principals behind the Startup class explained here:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.1
I understand that the class needs to include methods like ConfigureServices or Configure.
Why CreateDefaultBuilder(args).UseStartup<Startup>() does not mandate any base class or interface for better readability?
With this design approach, someone must read the documentation and know about the magic method names like ConfigureServices or Configure.
If this is part of a new class design mindset, then where can I read more about it?
c# design-patterns asp.net-core class-design
|
show 2 more comments
This is in regards to the design principals behind the Startup class explained here:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.1
I understand that the class needs to include methods like ConfigureServices or Configure.
Why CreateDefaultBuilder(args).UseStartup<Startup>() does not mandate any base class or interface for better readability?
With this design approach, someone must read the documentation and know about the magic method names like ConfigureServices or Configure.
If this is part of a new class design mindset, then where can I read more about it?
c# design-patterns asp.net-core class-design
2
"Magic names" would be names you have to create on your own and aren't documented. This allows you to have a Configure/ConfigureServices per environment and that cannot be known at the package-level. Sorry but this seems like rant.
– Camilo Terevinto
Nov 12 '18 at 0:56
1
Convention. I'd argue that it allows more flexibility, and requires the developer to do less work. TakeConfigureServices, by default that's avoid. If you use another DI container, you need to returnIServiceProviderfromConfigureServices. How would you do that with a base class? Always have to return it? Also, by default, when you create an ASP.NET Core project in Visual Studio, those methods will be created for you.
– John
Nov 12 '18 at 1:13
1
Please explain how interfaces or abstract classes would mitigate the issue of reading documentation.
– CodingYoshi
Nov 12 '18 at 1:15
@CodingYoshi, sorry, not following. Can you elaborate your comment a bit.
– Allan Xu
Nov 12 '18 at 1:51
@CamiloTerevinto, in regards to your "This allows you to have a Configure/ConfigureServices per environment" - can you elaborate a bit or refer me to a doc that explain
– Allan Xu
Nov 12 '18 at 1:53
|
show 2 more comments
This is in regards to the design principals behind the Startup class explained here:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.1
I understand that the class needs to include methods like ConfigureServices or Configure.
Why CreateDefaultBuilder(args).UseStartup<Startup>() does not mandate any base class or interface for better readability?
With this design approach, someone must read the documentation and know about the magic method names like ConfigureServices or Configure.
If this is part of a new class design mindset, then where can I read more about it?
c# design-patterns asp.net-core class-design
This is in regards to the design principals behind the Startup class explained here:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.1
I understand that the class needs to include methods like ConfigureServices or Configure.
Why CreateDefaultBuilder(args).UseStartup<Startup>() does not mandate any base class or interface for better readability?
With this design approach, someone must read the documentation and know about the magic method names like ConfigureServices or Configure.
If this is part of a new class design mindset, then where can I read more about it?
c# design-patterns asp.net-core class-design
c# design-patterns asp.net-core class-design
edited Nov 12 '18 at 5:06
marc_s
571k12811031252
571k12811031252
asked Nov 12 '18 at 0:49
Allan Xu
1,74711837
1,74711837
2
"Magic names" would be names you have to create on your own and aren't documented. This allows you to have a Configure/ConfigureServices per environment and that cannot be known at the package-level. Sorry but this seems like rant.
– Camilo Terevinto
Nov 12 '18 at 0:56
1
Convention. I'd argue that it allows more flexibility, and requires the developer to do less work. TakeConfigureServices, by default that's avoid. If you use another DI container, you need to returnIServiceProviderfromConfigureServices. How would you do that with a base class? Always have to return it? Also, by default, when you create an ASP.NET Core project in Visual Studio, those methods will be created for you.
– John
Nov 12 '18 at 1:13
1
Please explain how interfaces or abstract classes would mitigate the issue of reading documentation.
– CodingYoshi
Nov 12 '18 at 1:15
@CodingYoshi, sorry, not following. Can you elaborate your comment a bit.
– Allan Xu
Nov 12 '18 at 1:51
@CamiloTerevinto, in regards to your "This allows you to have a Configure/ConfigureServices per environment" - can you elaborate a bit or refer me to a doc that explain
– Allan Xu
Nov 12 '18 at 1:53
|
show 2 more comments
2
"Magic names" would be names you have to create on your own and aren't documented. This allows you to have a Configure/ConfigureServices per environment and that cannot be known at the package-level. Sorry but this seems like rant.
– Camilo Terevinto
Nov 12 '18 at 0:56
1
Convention. I'd argue that it allows more flexibility, and requires the developer to do less work. TakeConfigureServices, by default that's avoid. If you use another DI container, you need to returnIServiceProviderfromConfigureServices. How would you do that with a base class? Always have to return it? Also, by default, when you create an ASP.NET Core project in Visual Studio, those methods will be created for you.
– John
Nov 12 '18 at 1:13
1
Please explain how interfaces or abstract classes would mitigate the issue of reading documentation.
– CodingYoshi
Nov 12 '18 at 1:15
@CodingYoshi, sorry, not following. Can you elaborate your comment a bit.
– Allan Xu
Nov 12 '18 at 1:51
@CamiloTerevinto, in regards to your "This allows you to have a Configure/ConfigureServices per environment" - can you elaborate a bit or refer me to a doc that explain
– Allan Xu
Nov 12 '18 at 1:53
2
2
"Magic names" would be names you have to create on your own and aren't documented. This allows you to have a Configure/ConfigureServices per environment and that cannot be known at the package-level. Sorry but this seems like rant.
– Camilo Terevinto
Nov 12 '18 at 0:56
"Magic names" would be names you have to create on your own and aren't documented. This allows you to have a Configure/ConfigureServices per environment and that cannot be known at the package-level. Sorry but this seems like rant.
– Camilo Terevinto
Nov 12 '18 at 0:56
1
1
Convention. I'd argue that it allows more flexibility, and requires the developer to do less work. Take
ConfigureServices, by default that's a void. If you use another DI container, you need to return IServiceProvider from ConfigureServices. How would you do that with a base class? Always have to return it? Also, by default, when you create an ASP.NET Core project in Visual Studio, those methods will be created for you.– John
Nov 12 '18 at 1:13
Convention. I'd argue that it allows more flexibility, and requires the developer to do less work. Take
ConfigureServices, by default that's a void. If you use another DI container, you need to return IServiceProvider from ConfigureServices. How would you do that with a base class? Always have to return it? Also, by default, when you create an ASP.NET Core project in Visual Studio, those methods will be created for you.– John
Nov 12 '18 at 1:13
1
1
Please explain how interfaces or abstract classes would mitigate the issue of reading documentation.
– CodingYoshi
Nov 12 '18 at 1:15
Please explain how interfaces or abstract classes would mitigate the issue of reading documentation.
– CodingYoshi
Nov 12 '18 at 1:15
@CodingYoshi, sorry, not following. Can you elaborate your comment a bit.
– Allan Xu
Nov 12 '18 at 1:51
@CodingYoshi, sorry, not following. Can you elaborate your comment a bit.
– Allan Xu
Nov 12 '18 at 1:51
@CamiloTerevinto, in regards to your "This allows you to have a Configure/ConfigureServices per environment" - can you elaborate a bit or refer me to a doc that explain
– Allan Xu
Nov 12 '18 at 1:53
@CamiloTerevinto, in regards to your "This allows you to have a Configure/ConfigureServices per environment" - can you elaborate a bit or refer me to a doc that explain
– Allan Xu
Nov 12 '18 at 1:53
|
show 2 more comments
1 Answer
1
active
oldest
votes
Not sure about the downvotes, but there are several reasons why its done the way its done.
One of the more obvious reasons is, because you can inject services into Configure method, such as
public void Configure(IAppBulder app, IMyService myService)
myService.DoSomething();
Obviously, you can't do that with interfaces, abstract classes or inheritence.
The second reason why its done by convention method is, that there is not only Configure/ConfigureServices method, there is an infinite number of environment-dependent configure methods.
public void Configure(IAppBulder app)
public void ConfigureDevelopment(IAppBulder app)
public void ConfigureProduction(IAppBulder app)
public void ConfigureStaging(IAppBulder app)
public void ConfigureSomethingElse(IAppBulder app)
and depending on your environment variable for ASPNET_ENVIRONMENT a different method will be chosen and executed (or the default Configure/ConfigureServices if no matching environment specific method was found).
None of this is possible with traditional OOP (inheritance/interfaces/abstract classes).
The same applies to other parts of ASP.NET Core, like Middlewares and the Invoke Method. The Invoke method can also have dependencies injected into it, but in order to call the next middleware you simply do
await next?.Invoke();
and do not have to worry which dependencies the next middleware requires or may take.
And to be complete, one can also have multiple Startup classes with the default method names (Configure/ConfigureServices) named StartupDevelopment, StartupProduction, Startup (as fallback) and ASP.NET Core will pick up the correct one based on Environment variable set
Everything you have mentioned can be done with both interfaces and/or inheritance. I am not sure why you think it cannot be.
– CodingYoshi
Nov 12 '18 at 13:05
2
@CodingYoshi: Well, tell me how do you create a interface which accepts an unlimited number and combination of type parameters lol. Of course in strong typed manner, meansparam objectisn't suitable in here, since you can't define dependencies that way. Remember, we are talking about methods on interfaces and abstract classes here, not about constructor injection which is an implementation detail
– Tseng
Nov 12 '18 at 13:07
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254735%2fwhy-is-asp-net-cores-startup-class-not-an-interface-or-abstract-class%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Not sure about the downvotes, but there are several reasons why its done the way its done.
One of the more obvious reasons is, because you can inject services into Configure method, such as
public void Configure(IAppBulder app, IMyService myService)
myService.DoSomething();
Obviously, you can't do that with interfaces, abstract classes or inheritence.
The second reason why its done by convention method is, that there is not only Configure/ConfigureServices method, there is an infinite number of environment-dependent configure methods.
public void Configure(IAppBulder app)
public void ConfigureDevelopment(IAppBulder app)
public void ConfigureProduction(IAppBulder app)
public void ConfigureStaging(IAppBulder app)
public void ConfigureSomethingElse(IAppBulder app)
and depending on your environment variable for ASPNET_ENVIRONMENT a different method will be chosen and executed (or the default Configure/ConfigureServices if no matching environment specific method was found).
None of this is possible with traditional OOP (inheritance/interfaces/abstract classes).
The same applies to other parts of ASP.NET Core, like Middlewares and the Invoke Method. The Invoke method can also have dependencies injected into it, but in order to call the next middleware you simply do
await next?.Invoke();
and do not have to worry which dependencies the next middleware requires or may take.
And to be complete, one can also have multiple Startup classes with the default method names (Configure/ConfigureServices) named StartupDevelopment, StartupProduction, Startup (as fallback) and ASP.NET Core will pick up the correct one based on Environment variable set
Everything you have mentioned can be done with both interfaces and/or inheritance. I am not sure why you think it cannot be.
– CodingYoshi
Nov 12 '18 at 13:05
2
@CodingYoshi: Well, tell me how do you create a interface which accepts an unlimited number and combination of type parameters lol. Of course in strong typed manner, meansparam objectisn't suitable in here, since you can't define dependencies that way. Remember, we are talking about methods on interfaces and abstract classes here, not about constructor injection which is an implementation detail
– Tseng
Nov 12 '18 at 13:07
add a comment |
Not sure about the downvotes, but there are several reasons why its done the way its done.
One of the more obvious reasons is, because you can inject services into Configure method, such as
public void Configure(IAppBulder app, IMyService myService)
myService.DoSomething();
Obviously, you can't do that with interfaces, abstract classes or inheritence.
The second reason why its done by convention method is, that there is not only Configure/ConfigureServices method, there is an infinite number of environment-dependent configure methods.
public void Configure(IAppBulder app)
public void ConfigureDevelopment(IAppBulder app)
public void ConfigureProduction(IAppBulder app)
public void ConfigureStaging(IAppBulder app)
public void ConfigureSomethingElse(IAppBulder app)
and depending on your environment variable for ASPNET_ENVIRONMENT a different method will be chosen and executed (or the default Configure/ConfigureServices if no matching environment specific method was found).
None of this is possible with traditional OOP (inheritance/interfaces/abstract classes).
The same applies to other parts of ASP.NET Core, like Middlewares and the Invoke Method. The Invoke method can also have dependencies injected into it, but in order to call the next middleware you simply do
await next?.Invoke();
and do not have to worry which dependencies the next middleware requires or may take.
And to be complete, one can also have multiple Startup classes with the default method names (Configure/ConfigureServices) named StartupDevelopment, StartupProduction, Startup (as fallback) and ASP.NET Core will pick up the correct one based on Environment variable set
Everything you have mentioned can be done with both interfaces and/or inheritance. I am not sure why you think it cannot be.
– CodingYoshi
Nov 12 '18 at 13:05
2
@CodingYoshi: Well, tell me how do you create a interface which accepts an unlimited number and combination of type parameters lol. Of course in strong typed manner, meansparam objectisn't suitable in here, since you can't define dependencies that way. Remember, we are talking about methods on interfaces and abstract classes here, not about constructor injection which is an implementation detail
– Tseng
Nov 12 '18 at 13:07
add a comment |
Not sure about the downvotes, but there are several reasons why its done the way its done.
One of the more obvious reasons is, because you can inject services into Configure method, such as
public void Configure(IAppBulder app, IMyService myService)
myService.DoSomething();
Obviously, you can't do that with interfaces, abstract classes or inheritence.
The second reason why its done by convention method is, that there is not only Configure/ConfigureServices method, there is an infinite number of environment-dependent configure methods.
public void Configure(IAppBulder app)
public void ConfigureDevelopment(IAppBulder app)
public void ConfigureProduction(IAppBulder app)
public void ConfigureStaging(IAppBulder app)
public void ConfigureSomethingElse(IAppBulder app)
and depending on your environment variable for ASPNET_ENVIRONMENT a different method will be chosen and executed (or the default Configure/ConfigureServices if no matching environment specific method was found).
None of this is possible with traditional OOP (inheritance/interfaces/abstract classes).
The same applies to other parts of ASP.NET Core, like Middlewares and the Invoke Method. The Invoke method can also have dependencies injected into it, but in order to call the next middleware you simply do
await next?.Invoke();
and do not have to worry which dependencies the next middleware requires or may take.
And to be complete, one can also have multiple Startup classes with the default method names (Configure/ConfigureServices) named StartupDevelopment, StartupProduction, Startup (as fallback) and ASP.NET Core will pick up the correct one based on Environment variable set
Not sure about the downvotes, but there are several reasons why its done the way its done.
One of the more obvious reasons is, because you can inject services into Configure method, such as
public void Configure(IAppBulder app, IMyService myService)
myService.DoSomething();
Obviously, you can't do that with interfaces, abstract classes or inheritence.
The second reason why its done by convention method is, that there is not only Configure/ConfigureServices method, there is an infinite number of environment-dependent configure methods.
public void Configure(IAppBulder app)
public void ConfigureDevelopment(IAppBulder app)
public void ConfigureProduction(IAppBulder app)
public void ConfigureStaging(IAppBulder app)
public void ConfigureSomethingElse(IAppBulder app)
and depending on your environment variable for ASPNET_ENVIRONMENT a different method will be chosen and executed (or the default Configure/ConfigureServices if no matching environment specific method was found).
None of this is possible with traditional OOP (inheritance/interfaces/abstract classes).
The same applies to other parts of ASP.NET Core, like Middlewares and the Invoke Method. The Invoke method can also have dependencies injected into it, but in order to call the next middleware you simply do
await next?.Invoke();
and do not have to worry which dependencies the next middleware requires or may take.
And to be complete, one can also have multiple Startup classes with the default method names (Configure/ConfigureServices) named StartupDevelopment, StartupProduction, Startup (as fallback) and ASP.NET Core will pick up the correct one based on Environment variable set
edited Nov 12 '18 at 14:16
answered Nov 12 '18 at 8:56
Tseng
33.1k590121
33.1k590121
Everything you have mentioned can be done with both interfaces and/or inheritance. I am not sure why you think it cannot be.
– CodingYoshi
Nov 12 '18 at 13:05
2
@CodingYoshi: Well, tell me how do you create a interface which accepts an unlimited number and combination of type parameters lol. Of course in strong typed manner, meansparam objectisn't suitable in here, since you can't define dependencies that way. Remember, we are talking about methods on interfaces and abstract classes here, not about constructor injection which is an implementation detail
– Tseng
Nov 12 '18 at 13:07
add a comment |
Everything you have mentioned can be done with both interfaces and/or inheritance. I am not sure why you think it cannot be.
– CodingYoshi
Nov 12 '18 at 13:05
2
@CodingYoshi: Well, tell me how do you create a interface which accepts an unlimited number and combination of type parameters lol. Of course in strong typed manner, meansparam objectisn't suitable in here, since you can't define dependencies that way. Remember, we are talking about methods on interfaces and abstract classes here, not about constructor injection which is an implementation detail
– Tseng
Nov 12 '18 at 13:07
Everything you have mentioned can be done with both interfaces and/or inheritance. I am not sure why you think it cannot be.
– CodingYoshi
Nov 12 '18 at 13:05
Everything you have mentioned can be done with both interfaces and/or inheritance. I am not sure why you think it cannot be.
– CodingYoshi
Nov 12 '18 at 13:05
2
2
@CodingYoshi: Well, tell me how do you create a interface which accepts an unlimited number and combination of type parameters lol. Of course in strong typed manner, means
param object isn't suitable in here, since you can't define dependencies that way. Remember, we are talking about methods on interfaces and abstract classes here, not about constructor injection which is an implementation detail– Tseng
Nov 12 '18 at 13:07
@CodingYoshi: Well, tell me how do you create a interface which accepts an unlimited number and combination of type parameters lol. Of course in strong typed manner, means
param object isn't suitable in here, since you can't define dependencies that way. Remember, we are talking about methods on interfaces and abstract classes here, not about constructor injection which is an implementation detail– Tseng
Nov 12 '18 at 13:07
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254735%2fwhy-is-asp-net-cores-startup-class-not-an-interface-or-abstract-class%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
"Magic names" would be names you have to create on your own and aren't documented. This allows you to have a Configure/ConfigureServices per environment and that cannot be known at the package-level. Sorry but this seems like rant.
– Camilo Terevinto
Nov 12 '18 at 0:56
1
Convention. I'd argue that it allows more flexibility, and requires the developer to do less work. Take
ConfigureServices, by default that's avoid. If you use another DI container, you need to returnIServiceProviderfromConfigureServices. How would you do that with a base class? Always have to return it? Also, by default, when you create an ASP.NET Core project in Visual Studio, those methods will be created for you.– John
Nov 12 '18 at 1:13
1
Please explain how interfaces or abstract classes would mitigate the issue of reading documentation.
– CodingYoshi
Nov 12 '18 at 1:15
@CodingYoshi, sorry, not following. Can you elaborate your comment a bit.
– Allan Xu
Nov 12 '18 at 1:51
@CamiloTerevinto, in regards to your "This allows you to have a Configure/ConfigureServices per environment" - can you elaborate a bit or refer me to a doc that explain
– Allan Xu
Nov 12 '18 at 1:53