Net core MVC clean architecture without repository pattern - asp.net-core

I'm trying to create a MVC application in net core 2.1 using the eshoponweb example application. Ive read that in entity Framework core there's no great benefit of putting a repository layer in and to just use the ef dbcontext directly. How would I do this in a clean architecture scenerio. In the example application the dB context is in the infrastructure layer and the business services logic is all in the application core. I thought about moving either of these but then won't that prevent the separation that clean architecture is looking to achieve. https://github.com/dotnet-architecture/eShopOnWeb and https://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-core/

I think where a lot of developers get hung up is in thinking that you need your own layers. In onion architecture, you'll generally have a "data" layer, typically referred to as DAL. When you're using an ORM like EF, that is your data layer. In other words, rather than having a separate class library you create to work with the database, EF is that library, and therefore, you'd use it just like you'd use your own DAL library, if you had one.
Try not to get so hung up on layers and "clean" architecture. In truth, the cleanest architecture is a single project. It's only when things start to get unwieldy with that, that it makes sense to break out "layers". In other words, build the simplest unit of functionality you can. If there's a bunch of code involved, you find yourself repeating code, you have too many dependencies, etc. then start to break stuff out as part of the refactoring process. Eventually, you may end up with all the fancy layers and 100 different class libraries, or whatever, but it's folly to try to start there. If your app doesn't actually need something, it's stupid to add it. Plain and simple.
For what it's worth, this is probably one of the most unsung benefits of TDD, or test driven development. You write a test to ensure that one particular thing happens that you want, then you write the code to satisfy that test. Importantly, you only write the code to satisfy that test. That means naturally, you start simple and move to complexity. The refactor cycle of the old red-green-refactor TDD approach is where you clean up the code, abstracting things where necessary, moving logic out into reusable libraries and such. Even if you don't do the whole test-first approach to coding, it's still highly beneficial to look at development this way. You know what you need to build, so build the most simplistic thing that technically satisfies that requirement. Then refactor. Build the next requirement, and refactor again. Let you application naturally grow into what it actually needs to be, rather than trying to assert some sort of architecture, pattern, or process on it from the get-go.

Related

Method JavaFx TreeItem getRoot() is not visible. What is the OOP/MVC reason it is not?

I needed to get the root item of a TreeView. The obvious way to get it is to use the getRoot() on the TreeView. Which I use.
I like to experiment, and was wondering if I can get same root, buy climbing up the tree from a leaf item (a TreeItem), using recursively getParent() until the result is NULL.
It is working as well, and, in my custom TreeItem, I added a public method 'getRoot()' to play around with it. Thus finding out this method does already exist in parent TreeItem, but is not exposed.
My question : Why would it not be exposed ? Is is a bad practice regarding OOP / MVC architecture ?
The reason for the design is summed up by kleopatra's comment:
Why would it not be exposed I would pose it the other way round: why should it? It's convenience api at best, easy to implement by clients, not really needed - adding such to a framework/toolkit tends to exploding api/implementation to maintain.
JavaFX is filled with decisions like this on purpose. A lot of the reasoning is based on experience (good and bad) from AWT/Spring. Just some examples:
For specifying execution on the UI thread, there is a runLater API, but no invokeAndWait API like Swing, even though it would be easy for the framework to provide such an API and it has been requested.
Providing an invokeAndWait API means that naive (and experienced :-) developers could use it incorrectly to accidentally deadlock threads.
Lots of classes are final and not extensible.
Sometimes developers want to extend classes, but can't because they are final. This means that they can't over-ride a lot of the built-in tested functionality of the framework and accidentally break it that way. Instead they can usually use aggregation over inheritance to do what they need. The framework forces them to do so in order to protect itself and them.
Color objects are immutable.
Immutable objects in general make stuff easier to maintain.
Native look and feels aren't part of the framework.
You can still create them if you want, and there are 3rd party libraries that do that, but it doesn't need to be in the core framework.
The application programming interface is single threaded not multi-threaded.
Because the developers of the framework realized that multi-threaded UI frameworks are a failed dream.
The philosophy was to code to make the 80% use case easier and the the 20% use case (usually) possible, using additional user or 3rd party code, while making it difficult for the user code to accidentally (or intentionally) break the framework. You just stumbled upon one instance of an application of this philosophy.
There are a whole host of catch-phrases that you could use to describe the reason for this design approach. None of them are OOP or MVC specific. The underlying principles have been around far longer than software engineering, they are just approaches towards work and engineering in general. Here are some links if interested:
You ain't going to need it YAGNI
Minimal viable product MVP
Worse-is-better
Muntzing
Feature creep prevention
Keep it simple stupid KISS
Occam's razor

Why was cakePHP designed to use Inheritance over Composition even though it's mostly considered a bad design?

CakePHP Applications being made in our company tends to become unmaintainable as it becomes more complex. I figured that one specific reason is inheritance which makes the functions in child classes depends a lot on it's parent classes and vice-versa (implementing template method pattern). Why is CakePHP designed this way and not friendly in using Dependency Injection, Strategies, or Factory patterns?
There is not such a bad design as you claim in the framework. Sure, there are probably things that could be done better but I would like to see a more substantial critic including solid arguments and examples. I assume you're not using the framework as it was intended.
Let me quote the first paragraph from this page.
According to Eric Evans, Domain-driven design (DDD) is not a technology or a methodology. It’s a different way of thinking about how to organize your applications and structure your code. This way of thinking complements very well the popular MVC architecture. The domain model provides a structural view of the system. Most of the time, applications don’t change, what changes is the domain. MVC, however, doesn’t really tell you how your model should be structured. That’s why some frameworks don’t force you to use a specific model structure, instead, they let your model evolve as your knowledge and expertise grows.
You're not showing code (for a reason?) so I guess your problem comes from stuffing everything into the table objects in src/Model/Table/ or doing something similar.
But you're totally free to create a folder structure like
/src/Service
/src/Model/Domain
and then simply instantiate services as you need them in your controller actions. A service could be for example \App\Service\User\Registration and using objects from App\Model\Domain\User.
I agree that the framework in fact doesn't provide any recommendation or template structure for how this could look like. For exactly this topic there is a discussion going on here. Because of a lack of such a structure I've started working on a plugin that provides this. The plugin doesn't require but suggest the usage of DI containers for the people who want them.
Given the whole fancy topic around DI and DDD so far I would say there is not the one way to get things right but different paths as long as the code is easy to maintain. And honestly, as long as this goal is archived I really don't care about how you call it. :) I think many people tend do make this topic to academic instead of simply trying to be practical.
Not everybody is even needing that structure. It depends on if you're building a RAD CRUD application or a more complex app. Not every application needs a DDD approach. There are so many shades of gray when it comes to design the business layer, no matter how the framework would do it, somebody would always complain about it.
I personally almost never missed a DI container in CakePHP, not even in the biggest project having more than ~560 database tables which was a hospital management solution and it just worked well.
I would suggest you to ask a more specific question about your approach how you structured your code and showing your structure and code and then asking for advice on how to improve it instead of blaming the tool you're using in the first place without providing context.
Unfortunately CakePHP v3 can not compare to the Zend3/Laminas, Symfony or Laravel.It is 7-8 years behind the other frameworks.If you are using cake for years or it is your 1st and last framework it is normal to not realise that.But if you have to use it after Zend 3... cake seems like really bad ecosystem.
Bad documentation
Bad ORM
Poor Routing system
Bad Templating engine
Bad idea to mix Data Mapper and Active Record
DIC is totally missing
Components - not good but not terrible
...
And many more thinks that should not be underestimated like - lack of GOOD tutorials, pluigns/addons/packages
The above thinks make developers to follow bad practices that adds a lot of technical depth.
If you care just for - it works! But not how it works and why it is bad, cake will fit ok for you.
Cake can not scale as good as Symfony/Laminas if you are doing big project.(yea AWS/GC can help for scaling a lot of thinks but not for scaling source code)
Cake doesn't allow you rapid development like Laravel/Symfony for decent project.
I'm wondering who and WHY would start a new project today using Cake as it has zero benefits over the other frameworks.
Probably only devs who used only Cake for last decade and do not want to start learning new technologies or devs that thinks SOLID is just a fancy hype with zero benefits like design patterns, DRY and KISS
CakePHP framework supplies user interaction with databases using Active record, it means that exist a high coupling between business layer and database layer which has negative effects in unit testing and because of that the framework is not friendly with Dependency Injection. The same issue happens with Factory pattern, high coupling mentioned before makes more difficult use simulated objects in unit testing.
Hope it helps!
Alberto

How to unit test non-public logic

In some cases unit testing can be really difficult. Normally people say to only test your public API. But in some cases this is just not possible. If your public API depends on files or databases you can't unit test properly. So what do you do?
Because it's my first time TDD-ing, I'm trying to find "my style" for unit testing, since it seems there is just not the one way to do so. I found two approaches on this problem, that aren't flawless at all. On the one hand, you could try to friend your assemblies and test the features that are internal. On the other hand, you could implement interfaces (only for the purpose of unit testing) and create fake objects within your unit tests. This approach looks quite nice first but becomes more ugly as you try to transport data using these fakes.
Is there any "good" solution to this problem? Which of those is less flawed? Or is there even a third approach?
I made a couple of false starts in TDD, grappling with this exact same problem. For me the breakthrough came when I realized what my mentor meant when he said : "We don't want to test the framework." (In our case that was the .Net framework).
In your case it sounds as if you have some business logic that interfaces to files and databases. What I would do is to abstract the file and database logic in the thinnest layers possible. You can then use Mock (of fakes or stubs) to simulate the file and database layers. This will allow you to test scenarios like if-my-database-returns-this-kind-of-information-does-my-business-logic-handle-it-correctly? Likewise for file access you can test the code that figures out which file in which path to open and you can test that your logic would be able to pull apart the contents of any given file correctly and able to use it correctly.
If for example your file access layer consists of a single function that takes a path name and a file name and returns the contents of the file in a long string then you don't really need to test it because essentially you are making a single call to the framework/OS and there is not a lot that can go wrong there.
At the moment I am working on a system that wraps our database as a bunch of functions that return lists of POCO's. Easy to understand for the business layer and easy to simulate via mocks.
Working this way takes some getting used to but it is absolutely byoo-ti-full once it clicks in your mind.
Finally, from your question I guess that you are working with legacy code and trying to do TDD for a new component. This is quite a bit harder than doing TDD on a completely new development. If it is at all possible, try to do your first TDD attempts on new (or well isolated) systems. Once you have learnt the mechanics it would be a lot easier to introduce partially TDD'd bits to legacy systems.
If your public API depends on files or databases you can't unit test properly. So what do you do?
There is an abstraction level that can be used.
IFileSystem/ IFileStorage (for files)
IRepository/ IDataStorage (for databases)
Since this level is very thin its integration tests will be easy to write and maintain. All other code will be unit-test friendly because it is easy to mock interaction with filesystem and database.
On the one hand, you could try to friend your assemblies and test the features that are internal.
People face this problem when their classes violates single responsibility principle (SRP) and dependency injection (DI) is not used.
There is a good rule that classes should be tested via their public methods/properties only. If internal methods are used by others then it is acceptable to test them. Private or protected methods should not be made internal because of testing.
On the other hand, you could implement interfaces (only for the purpose of unit testing) and create fake objects within your unit tests.
Yes, interfaces are easy to mock because of limitations of mocking frameworks.
If you can create an instance (fake/stub) of a type then your dependency should not implement an interface.
Sometimes people use interfaces for their domain entities but I do not support them.
To simplify working with fakes there are two patterns used:
Object Mother
Test Data Builder
When I started writing unit tests I started with 'Object Mother'. Now I am using 'Test Data Builder's.
There are a lot of good ideas that can help you in the book Working Effectively with Legacy Code by Michael Feathers.
Don't let the hard stuff get in your way... If it's inherently hard to test due to db or file integration, just ignore it for the moment. Most likely you can refactor that hard to test stuff into easier to test stuff using mocks with Dependency Injection etc... Until then, test the easy stuff and get a good unit test suite built up... when you do the refactoring of the hard to test stuff, you will have a much higher confidence interval that it's not breaking anything else... And refactoring to make something more easily testable IS a good reason to refactor...

What dependency strategy suits this small app

I have a small PHP command line application that I am creating in order to learn some common design patterns and oop techniques.
I have set up all of my relevant classes so that they are not instantiating objects internally, but instead they are being given their objects they require via their constructor.
The problem now is how do I orchestrate everything so that each object gets the dependencies it requires. I have read about dependency injection containers and frameworks but this seems overkill for a small command line app + I am having a hard time understanding how they would fit into my application.
Currently the flow goes like this:
Program is executed by user at the command line
Bootstrap occurs, i.e. autoloader etc instantiated etc
I have a factory method that sets up the dependencies (all hard coded inside the class) and returns an application object. There around 2 dependencies for the main application and each of those has a further 2 dependencies each (this is the tricky part i think)
Application->run() is called.
What would be the best approach in terms of a balance between flexibility and simplicity as I dont believe the design (around the factory) is quite correct.
From the sounds of it your application is organised fairly well, construction is separate from the application logic and your dependencies are managed clearly.
You could of course add configurable dependencies or utilise a dependency injection frameworks, however, I would recommend avoiding both of these unless the application requires it. If you do start using a DI framework, make sure you keep everything cohesive even though you are using this magic tool and try and move everything away from the framework when it is possible (i.e. Having modules handle the internal dependencies through factories rather than rely on the framework). Split functionality into modules when it makes sense.
I am working on improvements to a large nebulous application that runs all of its dependencies through a DI framework and it is slow to start up and turns into a bit of a sack-o-crap and is not pleasant to work with, it is an application that does "everything" rather than delegate tasks onto modules and libraries and has zero unit tests.
The main thing to note is that there are a lot of solutions to every problem and learning different patterns is a great idea, there are many types of factory pattern, learn them all. Some are simple, some are more sophisticated, you will get a feeling for what works in different situations.
My personal recommendation, if your application works as you intend, it is organised as it sounds like it is, and if you haven't already (and the aim of the game is to improve your techniques), practice:
Documenting (write some documentation and throw it at a dev friend to see how they deal with it)
Testing (write some unit tests and then rewrite the application a different way)
Benchmarking (run profiling on your code and try to find ways to optimize it)
Try a different approach to factory loading, dynamic factory, builder pattern, framework, use the benchmarks to understand what you traded off.
Your application should work like this:
$app = new Application($arg1, $arg2);
$app->run();
All other classes should be instantiated in the Application, and passed as parameters to constructors of other classes. Rule of thumb is: any constructor should have less than 3 arguments. If you follow this rule everything will be fine.

Code generators or ORMs?

What do you suggest for Data Access layer? Using ORMs like Entity Framework and Hibernate OR Code Generators like Subsonic, .netTiers, T4, etc.?
For me, this is a no-brainer, you generate the code.
I'm going to go slightly off topic here because there's a bigger underlying fallacy at play. The fallacy is that these ORM frameworks solve the object/relational impedence mismatch. This claim is a barefaced lie.
I find the best way to resolve the object/relational impedance mismatch is to either use OOP exclusively and use an object database or use the idioms of the relational database exclusively and ignore OOP.
The abstraction "everything is a table" is to me, much more powerful than the abstraction "everything is a class." It takes less code, less intellectual effort and leads to faster code when you code to the database rather than to an object model.
To me this seems obvious. If your application is data driven then surely your code should be data driven too? Yet to say this is hugely controversial.
The central problem here is that OOP becomes a really leaky abstraction when used in conjunction with a database. Code that look perfectly sensible when written to the idioms of OOP looks completely insane when you see the traffic that code generates at the database. When that messiness becomes a performance problem, OOP is the first casualty.
There is really no way to resolve this. Databases work with sets of data. OOP focus on instances of classes. Trying to marry the two is always going to end in divorce.
So to answer your question, I believe you should generate your classes and try and make them map the underlying database structure as closely as possible.
Perhaps controversially, I've always felt that using code generators for the ADO.NET plumbing is fundamentally solving the wrong problem.
At some point, hopefully not too long after learning about Connection Strings, SqlCommands, DataAdapters, and all that, we notice that:
Such code is ugly
It is very boring to write
It's very easy to miss something if you're doing it by hand
It has to be repeated every time you want to access the database
So, the problem to solve is "how to do the same thing lots of times fast"?
I say no.
Using code generators to make this process quick still means that you have a ton of code, all the same, all over your business classes (or your data access layer, if you separate that from your business logic).
And then, if you want to do something generically (like track stored procedure usage, for instance), you end up having to customise your code generator if it doesn't already have the feature you want. And even if it does, you still have to regenerate everything all the time.
I like to do things once, not many times, no matter how fast I can do them.
So I rolled my own Data Access class that knows how to add parameters, set up and close connections, manage transactions, and other cool stuff. It only had to be written once, and calling its methods from a Business object that needs some database stuff done consists of one line of code.
When I needed to make the application support multithreaded database accesses, it required a change to the Data Access class only, and all the business classes just do what they already did.
There is no right answer it all depends on your project. As Simon points out if your application is all data driven, then it might make sense depending on the size and complexity of the domain to use non oop paradigm. I had a lot of success building a system using a Transaction Script pattern, which passed XML Messages around the system.
However this system started to break down after five or six years as the application grew in size and complexity (5 or 6 webs, several web services, tons of COM+ components, legacy and .net code, 8+ databases with 800+ tables 4,000+ procedures). No one knew what anything was, and duplication was running rampant.
There are other ways to alleviate the maintance then OOP; however, if you have a very complex domain then hainvg a rich domain model is ideal IMHO, as it allows for the business rules to be expressed in nice encapsulated components.
To answer your question, avoid code generators if you can. Code generators are a recipe for disaster, but if you do go with code generation do not modify the generated code. Also be sure to have a good process in place that is easy for developers to get the new generated code.
I recommend using either the following: ORM or hand roll a lightweight DAL. I am currently transitioning a project over to nHibernate off my hand rolled DAL and am having a lot of success; however, I like having the option of using either option. Further if you properly seperate your concerns (Data Access from Business Layer from Presentation) you can have a single service layer that might talk to a Dao (Data Access Object) that for one object is an ORM but for another is hand rolled). I like this flexibility as it allows to apply the best tool to the job.
I like nHibernate over a hand rolled DAL because while my DAL does abstract away most of the ADO.Net code you still have to write the code that takes a data reader to an object or an object and creates the parameters.
I've always preferred to go the code generator route, especially in C# where you can make use of extended classes to add functionality to the basic data objects.
Hate to say this, but it depends. If you find an ORM tool that fits your needs go for it. We wrote our own system in small steps while developing the application. We are using C++ and there are not that many tools out there anyway. Ours ended up being a XML description of the database, from that the SQL generation script and the basic object layer and metadata were generated.
Do your homework and evaluate theses tools and you will find a good fit for your needs.