dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.21k stars 9.95k forks source link

Better compose/organize/design pattern for all asp.net core developer #35367

Closed John0King closed 2 years ago

John0King commented 3 years ago

Now your are working on minimal APIs , but as an developer for doing a complex/big web application, that I will never ever to use it.
because we need a better and better compose/organize pattern for separate out project, sound familiar ? yes , Micro service, but not every app can/should use Micro service, and In fact , Micro Services are also need great compose/organize pattern for project, and This is why Java so popular in Web, the Apache Foundation create "Spring" and other "Spring Family" for Java, and with that , more design pattern and design concept are goes to every Java web develper's mind. with that , they write many architecture book/blog , and that make their community keep innovate (because the mind of DDD and implementation make them stop DRY (Do Not Repeat you self), they can do more with less, and many common component are release to maven, and share to everyone , and the new developer can use those maven packages as business components to simplify their mork ). But what about .Net ? the official way that from asp.net core team is to create a template with dotnet new , and to share your business components is to copy and past your code, Nuget can only bring "provider" packages like (database provider, authentication provider, rabbitMQ provider etc.) There are some company (like Volosoft's ABP) try to bring the same thing for .Net too, but after all , they are Commercial project (but free) and third party do not have the Influence , that means, there business components can only be used in there ecosystem.

I wasn't happy to see .net keep releasing those "toy or demo" apis when minimal APIs was released. why? Less code is more learn and more work to repeat.

So to bring every developer in Asp.Net Core ecosystem, the Asp.Net Core team should release a great compose pattern to help us to share our business component across different web services , that may contains virtual file system , modularization , isolation ,generic AOP and many other (and current feature like MVC/SignalR should optimize for that) .

Most importantly , to tech better design architecture/mind/concept for everyone inside asp.net core ecosystem . (Ps. the doc of best practice , for this, we should learn from Angular's document, not just about how to use, but also how to use it better)

davidfowl commented 3 years ago

I think this is already possible to with the primitives built into ASP.NET Core. It's not clear to me why this is difficult of what problems you already have today. In fact, its why things like orchard and ABP can exist on top of the core stack (and I'm sure there are many others that have been built on top).

If you'd like this to be actionable, I'd suggest breaking it up into concrete feature areas where there's pain points and scenarios that we can look at.

PS: We're all for improving primitives to make modular scenarios but not about to build something like ABP/Orchard/name another enterprise friendly framework here out of the box is a no go.

John0King commented 3 years ago

@davidfowl It's not about enterprise friendly , it's about ecosystem share. orchard component can only be shared to orchard , ABP components can only be shared with ABP, that make DRY not possible in asp.net core ecosystem. without a unified modularization primitives , we can not share our business logic and view to others, can we also can not consume other-one's common business logic on Nuget.org. and it's even hard to shared my own business logic to myself , because with only Asp.Net Core that on Asp.Net Core document site , we can't separate our logic/view and static files in different project .

And Spring in Java already became a standard, there are lots of project be open source with Java Spring on github everyday, and your can simple to pull there common logic (logic can be isolated) to your app with Maven . and there are many asp.net core app be opensource too (far less than java), but you can not use it unless you copy and modify it's code.

like I post in here Do you still know why we create a separated DLL after all those yeas using nuget ? => Share and DRY, but from I see on nuget , 99% of nuget packages that I can not use it in my project. because they can only be use under same "project/architecture/framework"

davidfowl commented 3 years ago

@davidfowl It's not about enterprise friendly , it's about ecosystem share. orchard component can only be shared to orchard , ABP components can only be shared with ABP, that make DRY not possible in asp.net core ecosystem. without a unified modularization primitives , we can not share our business logic and view to others, can we also can not consume other-one's common business logic on Nuget.org. and it's even hard to shared my own business logic to myself , because with only Asp.Net Core that on Asp.Net Core document site , we can't separate our logic/view and static files in different project .

So, your complaint is about the unit of modularization? In your world what does a module contain?

Right now, it's possible to extend multiple parts of an ASP.NET Core application but I think you're specifically talking about deploying a monolith build as separate projects (microservices during development, monolith at deployment time). Is that correct?

And Spring in Java already became a standard, there are lots of project be open source with Java Spring on github everyday, and your can simple to pull there common logic (logic can be isolated) to your app with Maven . and there are many asp.net core app be opensource too (far less than java), but you can not use it unless you copy and modify it's code.

Can you show some specific examples of this?

like I post in here Do you still know why we create a separated DLL after all those yeas using nuget ? => Share and DRY, but from I see on nuget , 99% of nuget packages that I can not use it in my project. because they can only be use under same "project/architecture/framework"

I do better with concrete examples of what you want to do, what has to be done today, what the pain points are, and what you would like to do.

I have an allergic reaction to building anything into the base of ASP.NET Core that isn't pay for play (you don't pay for it if you don't need it). That means module system and plugin system should be built on top of the core and shouldn't cost anything if an application doesn't need to use it. Same goes for multi-tenancy, it shouldn't need to infect every component.

davidfowl commented 3 years ago

I'll tell you the reason why you need to be more specific:

Those are some of the things that work today out of the box and what we're find continuing to fix as the framework becomes more mature.

It's not a goal of ASP.NET Core to have an ecosystem of plugins like a CMS. What we're building is an unopinionated set of primitives that people can build on top of. Primitives win, and opinionated verticals expire (I can name a few). Do I think these verticals should exist? Yes, absolutely, but do I think the ASP.NET Core team should build one? No, absolutely not.

We're on the plan of building more unopinionated primitives into the stack where it makes sense and having other higher-level platforms built on top that, picking the appropriate lego pieces for various verticals.

Let me outline some of the things that I think should not be built into the framework:

John0King commented 3 years ago
service.AddControllerWithView()

// vs

service.AddControllerWithViewForAssembly(typeof(MyBaseController).Assembly)

//or

service.AddMvcUnit(unit=> unit.AddControllerWithViewForAssembly(typeof(MyBaseController).Assembly) .AddFilters(...) )

and by adding modularization , doesn't means it must be a plugin

Plugin features that load assemblies by scanning for plugins in specific folders.

without a Module base class, every implement is different tush can not be shared , and The framework do not need to handle assembly load, the load job can be done in third party , but the Module can be shared.

and without the modularization , MVC and other components build inside the framework, will not consider for modularization isolation. without the plugin system, your team won't try to make the virtual file system direct in side .csproj.

and micro service do need share code between each service, and Abp can separate the Modular to a standalone host , and without change anything else. and I think DDD is service monolith app at it's born , and adapted to micro service without change because it's a good pattern.

I'm not complaining current there no such feature, I'm complaining we have not now, and will have not in future too! I‘m not complaining the .net community is smaller than java, I'm complaining you continue to separate us from one community to a bunch of smaller community because the new version drop us behind or some product do the something with different implementation. And I'm do complain why can not your team bring the thought/concept to everyone in .net (leaning resource of best practices) .
and I think that why Java goes stronger because every a newbie java developer use IOC,Moduler,AOP, DDD at begin and became better java developer and feed back to the community when they dive in.

It's possible to ship embedded resources (including static files) in libraries.

you means _content/namespace.of.your.assembly.name/static-file.js ? will you happy with the path , and what path should the host app use ? /static-app.js or _content/namespace.app/static-app.js

There'r many thing's that "you can" , but not the same behavior (or best practice).

This why I try to discussion with the title **'Better *** '

davidfowl commented 3 years ago

And I'm do complain why can not your team bring the thought/concept to everyone in .net (leaning resource of best practices) .

Because not everyone needs to build applications like this and we don't need to dictate down to application architecture. That can be left to frameworks built on top of the core (like spring is for java).

and micro service do need share code between each service, and Abp can separate the Modular to a standalone host , and without change anything else. and I think DDD is service monolith app at it's born , and adapted to micro service without change because it's a good pattern.

This is the end goal, right? You're trying to build a system that can be deployed as a monolith or a set of microservices without changing how that application is developed? You want each team to be able to work on a separate part of the project and them have them compose and be isolated. Is that right?

John0King commented 3 years ago

This is the end goal, right?

For implementation,Yes, to share common and isolated business logic across entire asp.net core ecosystem is my primary goal here.

and secondary goal is to improve the developer's thought/quality from beginning with the best practices of the DDD (or other better design architecture), and developer learning more architecture and eventually feedback to the .net community (same as first goal)

davidfowl commented 3 years ago

This is a pretty good example of what I think you're looking for (I'm guessing it's not complete though):

https://github.com/thinktecture-labs/aspnetcore-modular-monolith

and secondary goal is to improve the developer's thought/quality from beginning with the best practices of the DDD (or other better design architecture) , and developer learning more architecture and eventually feedback to the .net community (same as first goal)

This team doesn't do architecture recommendations and building a modular system like the one expressed above doesn't really help improve that. But I do hope the .NET community building these systems share best practices (we don't build anything like this ourselves and its why you should listen to the framework team on application architecture concerns) amongst each other!

John0King commented 3 years ago

@davidfowl
your team as the community leader of asp.net core , if your team won't release a "standard" eg. primitives , then the community will be separated to pieces with different implements . and make shared code harder. and this is what I'm asking to avoid , because asp.net core community still very small , and will be much smaller after separated . and now we use many java's component in Micro-service with docker (Kafka, zipkin,Apache SkyWalking,apollo, etc. ps: zipking, skywalking, apollo using spring)

and those default implementation should not goes to the framework , and be a nuget package instead.

davidfowl commented 3 years ago

I don't think lack of modules in ASP.NET Core have anything to do with that.

Anyway we're off topic. This issue has already been moved to discussions which means no concrete action will be taken.

begerard commented 3 years ago

Let me outline some of the things that I think should not be built into the framework:

  • Anything that does assembly scanning. Explicit registrations but be done for everything (MVC currently violates this)
  • Declarative dependency injection. Attributes that determine what components are services.
  • Plugin features that load assemblies by scanning for plugins in specific folders.

Sorry to hijack this conversation @davidfowl but is there guidance for building webservices which does not have this "things"? WebAPI don't seems to fit the bill :)

And more on the topic, having some sort of silver lining in building blocks (modules), for example with interface like we have with ILogger, would be beneficial in my opinion. Isn't there some architecture team out there in Microsoft which could share the load with you on that? A long time ago, such a team builded PRISM upon WPF and even if it did have gone out of flavor quickly, it still pushed the .Net ecosystem in the good direction I think (UI components, DI with MEF, etc.). There is also the Bing Team which works on modules in .Net Core as per a recent .Net Blog post, so maybe working with them to share their work would be a good starting point for the community.

davidfowl commented 3 years ago

Orchard already does that. Why not use it?

begerard commented 3 years ago

Well, I don't really know Orchard. They do look like they do great job, but it isn't clear to me what is their developers target, what is their roadmap, how they deprecate things... You can't exactly compare the Orchard Team with the .Net Team.

I already use non-MS FOSS tools in addition to .Net Core, but only on very specific tasks that I know I can replace without breaking everything. Application composition is not something you can replace easily, so yeah, having MS backing on that would be preferable. And the way ASP.Net core is build today seems not too far from it.

And, more as an anecdote than a real case, when IS4 was abandoned in favor of the non-free IS5 by its team, blowdart could have change the default recommended way to handle identity in ASP.Net templates for the Orchard Identity block. He did not.

While I love your work and how you always push for better architecture in ASP .Net Core David, I'd like a more "team" approach of the subject. @danroth27 is it possible to put this subjet on the list of things to discus internally? Of course it can wait for after the .Net6 rush ;)

davidfowl commented 3 years ago

You need to use non MS FOSS to build anything real and the .NET team does not want to be the one stop shop for everything, that kills innovation in the OSS community and we already get flack for that. .NET developers need to reconcile that fact, we're not going to build everything. This is why we're sticking to building primitives that others can build on.

begerard commented 3 years ago

Right, I think .Net needs some primitive to push the ecosystem of modular application in the same direction, and maybe reassure devs on this, but it's only my opinion. Maybe other ways like .Net Blog posts on the subject, or templates included in the ASP.Net workload, could be better solutions!

But I do think that the .Net ecosystem would be better off and evolve quicker with some guidance from your team :)

John0King commented 3 years ago

that kills innovation in the OSS community and we already get flack for that.

we are on the same line. but, I think less and less developer can do innovation if they all stuck in the basic things like (User system, permission system, rule system, email system, sms system and so on) , and here already many nuget package to resolve those basic and isolated thing, the problem is there no good way to compose them to the app that you design (eg. basic compose unit => module )

and, In fact I hope there more design architecture (DDD) to be share from asp.net core team directly [teach the thought]. The reason that Java web app so popular is that even newbie developer can develop a maintainable web app using Spring framework , and enterprise trust it because there are large user of Spring framework , (because there are a lot of solution and experience), and with the DDD thought fill the newbie developer's head, and the newbie developer will became a Senior Developer in less time. and I think that this the reason Java ecosystem so big (even the syntax of java is worth than C#).

dimohy commented 3 years ago

I hope the ASP.NET Core team doesn't offer anything at the same level as the Spring Framework. The Spring Framework was not created by the Java team. This sounds strange to me.

However, we do want developers to actively document guidelines or samples for actively taking advantage of ASP.NET Core. The current documentation is already good, but as a developer of service applications I don't know enough examples of other approaches.

It seems to make sense for the ASP.NET Core team to do this, or to create a forum where the community can actively participate in the form of these sample galleries.

leandro-almeida commented 3 years ago

I think ASP.NET Core is missing a Spring-like framework to make things easier. ABP.io is a great framework, but its not widely adopted like Spring, so if we adopt it in our business, when a new developer arrives, they dont know nothing about ABP.

ABP.io delivers much effort upfront, so i can focus on Business. Without a good framework, we have to implement all the good patterns from scratch. Its good for learning, but for delivering projects fast, its not. Things like automagic repositories, automagic entity history and auditing, permission system, etc are great features.

But i understand that this depends more on community than on the ASPNET Core team. Maybe Microsoft could hire the ABP guys and buy ABP.IO ? just kidding ;)

leandro-almeida commented 3 years ago

The samething about IdentityServer. Microsoft could write a opensource Keycloak competitor in .NET. Why not?

davidfowl commented 3 years ago

Yes, Microsoft could replace all of the 3rd party nuget packages and write them all inhouse but we'd like an ecosystem so we don't want to do that.

John0King commented 3 years ago

@davidfowl Nobody want MS replace all of the 3rd party , the truth is that MS give MS a big head rule: "every package in default template must be include inside .net sdk ".

but we'd like an ecosystem

what kind of ecosystem do you want ? same thing everywhere ? you don't need multiple same feature package (like logging,permission,audit) in our project , we only use single one package of them. there are many logging framework like NLog, serialLog , Log4Net, but eventually you only use one of them. Yes, there are multiple choice is good,but can you choose it in really ? but what I am asking is:

  1. better design pattern (DDD thought) for every web service (exclude for simple demo)
  2. an unify way to compose your code and bring every library to unify model ( current what I can imagine is module) , and make our whole entire community into one big community. The Java Spring community can achieve that so can we.
  3. common design pattern use 3rd party library in default template (eg. AOP , the Micorosft.Extension.DI is the only DI container lack of this; Property Inject , same as previous one), and a suggestion is to add service.AddProxy<TService,TProxy> where TProxy:IObjectProxy<T> and it just add an IObjectProxy<T> to the collection, that will make all 3rd party library can use AOP
  4. tech the thought (with doc, in another section): eg. CQRS and it's best practice , AOP and it's best practice , and so on.
davidfowl commented 3 years ago

I don't think everyone should do DDD or use design patterns or be forced into strict design patterns by ASP.NET Core. They can pick a framework that gels with their view of the world on how to build applications. Choice is a good thing. I do want an ecosystem that builds the same thing 10 times because each of those things comes with an opinion that someone might prefer over the default options.

I'd like to see all of those things provided by 3rd party packages, we've already built the plumbing required.

If you can do better with spring because it provides out of box packages for every thing you need then I'd suggest using it. ASP.NET Core isn't spring.

If you want spring on ASP.NET Core, consider Steeltoe.

We will not be providing those things out of the box.

John0King commented 3 years ago

I don't think everyone should do DDD or use design patterns or be forced into strict design patterns by ASP.NET Core.

everyone don't , every-company do , and any project that keep maintain over 1 year do (no matter they are DDD or something else) .

If you can do better with spring because it provides out of box packages

I'm not very familiar with Spring, but I think Spring not provide everything , they provide the features for most project need, and people can chose not to use them, and 3rd party use the Spring provided pattern , so you can simply plug them into your project . Another example is Angular (which is what I familiar ), you can plugin almost every 3rd party packages into your project, because everyone is using Service Module HttpClient HttpClientInterceptor and everything angular provided Concept , and you can chose to not use angular's httpclient , and you can not use angular's form validator.

We will not be providing those things out of the box.

Well, I'm here just to provide my suggestion before my company switch to Java Spring . and I'll use Spring anyway , no matter I want or not (which I'm not).

anyway , happy coding

davidfowl commented 3 years ago

ASP.NET provides similar primitives and 3rd parties have built many things on top (like the frameworks and capabilities mentioned above).

mariuszkochanowski commented 2 years ago

I think that net core community would benefit from production grade frameworks similar to following framework that is used in training sessions about ddd and microservices in Poland.

https://github.com/snatch-dev/Convey

https://github.com/snatch-dev/Chronicle

example project:

https://github.com/devmentors/Pacco

https://github.com/devmentors?q=pacco&type=&language=&sort=

youtube: https://www.youtube.com/watch?v=5SLyrETnJoE

davidfowl commented 2 years ago

Convey - a simple recipe for .NET Core microservices

I love this framing, it's recipe, not a framework. It's made up for lots of packages from nuget that exists today. IMHO the docs that are scenario specific are much more helpful that the framework itself. I don't see what it adds over the core framework beyond the curation of these packages and that's something we should definitely do more of.

davidfowl commented 2 years ago

Also I recommend people watch this ASP.NET community stand up with ABP.io (ASP.NET Boilerplate). It has everything built in.

mariuszkochanowski commented 2 years ago

I am just a developer that uses Convey at work and just want to toss some ideas.

Maybe Convey it's more like recipe than framework but i think that it contains some well designed patterns to develop distributed applications like onion architecture (separation of aplication into : infractructure, application, ddd, api sections/dlls), microservices - separation of parts of application into microservices and communication between them - rabbitmq (lack of kafka), sagas, distributed tracing - jaeger etc.

I searched for other similar and more robust/production grade alternative recipes/framework for start to building well designed microservice applications but i didn't find it.

I am aware of frameworks like akka.net and orleans but these implements actor model.

Free tutorial that uses this framework to develop distributed application on docker: https://www.youtube.com/watch?v=s4fd3PRlOcw

davidfowl commented 2 years ago

Awesome!

ghost commented 2 years ago

Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.

This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue!

John0King commented 2 years ago

😅