How do I split a large Blazor component, when it has a large object graph as its data? - entity-framework-core

I have an ASP.NET Blazor server-side project, using EF Core. One of the pages is getting quite large. Apart from any other reasons for keeping code files a reasonable size, the large size causes significant delays when recompiling.
I would like to split it down into smaller components, but the problem is that the whole page represents a fairly large object graph, parts of which are used in multiple places on the page.
Imagine a page that shows details for a company. The company has many employees, each of whom can claim expenses, which are added to the company's transactions list. The company itself has income and expense, so that adds more transactions. Other parts of the company object graph might also have associated expenses. This is a very simplified (and fictitious) sample of the idea. The page has various sections, such as one for employee details, which shows their transactions, as well as an overall transaction list.
At various places, you can add transactions, which get associated with the employee (or whatever), and are shown on both that transaction list and the main one. All of this is done with individual forms for each action, it's not one huge form for the whole object graph.
If I were to split the component down, I would be faced with one of the following choices (unless someone can suggest another)...
Have each smaller component inject its own DbContext and handle its own data access. This is fine in theory, but would cause concurrency problems as it would mean that different components were saving changes to the same entities. It would also require a lot of events to inform the parent component that data had changed in the subcomponents, which would end up very messy.
Have each smaller component have parameters for the bits of the object graph they handle. This avoids any concurrency issues, as only the parent component would be doing any data access. I'm not sure if it would avoid the need for events, as it depends on how well Blazor would notice if a part of the graph passed to a subcomponent changed.
Pass the DbContext in to each smaller component as a parameter. Again, this avoids any concurrency issues, but really feels like the wrong way to do it.
Anyone able to guide me as to the best way to split this up?
Thanks

If you have lots of sub-components accessing the data in the Form [your top level component - some sort of dashboard?] then you probably have quite a bit of plumbing to try and keep everything in sync, or lots of rendering going on if you are cascading objects. How often are you calling StateHasChanged?
Without some code I can only answer in very generic terms.
Your first step is to separate out your data and data management from your components and form. Move the data and the database into a DI service. The scope depends on what you're doing: Transient or Scoped. You can then use normal events to signal updates to components that need to render if something changes. There's an answer here that shows how to do this - https://stackoverflow.com/a/69562295/13065781.
[Opinionated] You also need to understand that by building a complex object (your DataGraph) and then letting EF manage it's state, [in Clean Design terms] you're building core application logic (the relationships between your basic data objects) into your infrastructure layer. The advantage is it makes things easy, and saves a lot of coding. The disadvantages come to light over time.

Related

Keeping track of changed properties in JPA

Currently, I'm working on a Java EE project with some non-trivial requirements regarding persistence management. Changes to entities by users first need to be applied to some working copy before being validated, after which they are applied to the "live data". Any changes on that live data also need to have some record of them, to allow auditing.
The entities are managed via JPA, and Hibernate will be used as provider. That is a given, so we don't shy away from Hibernate-specific stuff. For the first requirement, two persistence units are used. One maps the entities to the "live data" tables, the other to the "working copy" tables. For the second requirement, we're going to use Hibernate Envers, a good fit for our use-case.
So far so good. Now, when users view the data on the (web-based) front-end, it would be very useful to be able to indicate which fields were changed in the working copy compared to the live data. A different colour would suffice. For this, we need some way of knowing which properties were altered. My question is, what would be a good way to go about this?
Using the JavaBeans API, a PropertyChangeListener could suffice to be notified of any changes in an entity of the working copy and keep a set of them. But the set would also need to be persisted, since the application could be restarted and changes can be long-lived before they're validated and applied to the live data. And applying the changes on the live data to obtain the working copy every time it is needed isn't feasible (hence the two persistence units).
We could also compare the working copy to the live data and find fields that are different. Some introspection and reflection code would suffice, but again that seems rather processing-intensive, not to mention the live data would need to be fetched.
Maybe I'm missing something simple, or someone know of a wonderful JPA/Hibernate feature I can use. Even if I can't avoid making (a) separate database table(s) for storing such information until it is applied to the live data, some best-practices or real-life experience with this scenario could be very useful.
I realize it's a semi-open question but surely other people must have encountered a requirement like this. Any good suggestion is appreciated, and any pointer to a ready-made solution would be a good candidate as accepted answer.
Maybe you can use the Hibernate flush entity event listener. The dirty properties are calculated before the flush. You can store them somewhere in your database.
A sample code of using the dirty properties feature of Hibernate which may give you an idea.

Is Entity Framework also persistance layer?

OK. I know that Entity Framework is ORM. We use it for mapping data from database to object model, and from objects to relational data. But where it fits in a context of persistance layer? Can we say that persistance layer is also Entity Framework?
I would say - No! There are a lot of articles about this topic. But in general you don't want your object-relational mapper to be data-persistent. In fact exactly the opposite, keeping it persistent ignorant you can benefit by using your data classes with different types of data providers such as relational databases, web services, XML files and what not.
To keep data persistence you may take advantage of different design patterns like Repository pattern and Unit Of Work so you can really decouple you business layer from your data layer.
Ok, to make myself clear since it's very difficult through comments, here's an update to what I wanted to explain. Please have in mind that this is just my interpretation, and the way I'm using EF, I've been using it in different projects (desktop and web) but it's not universal, but still covers a lot of the most common scenarios.
So since I'm a big fan of Code First I'll write from this prespective. The Database Model is where your entities lies. Later on based on those entities the EF will generate your database. So what is important on this stage of development - you want to have you database normalized and you want all navigation properties set correctly. Not so trivial tasks as it may seems but that it's, you just care about how efficient your database will be.
Now comes the tricky moment somehow you should deliver you data to the business layer and it's true - as far as we are talking only about data from a database using repository is very arguable. However even then the one advantage that you get when having this Repository between the data and the business logic is that you don't have to take in mind the business needs while creating the data model, and after that this doesn't make it any harder to use your data from inside the business layer even though what exactly will your front end looks like at the time you create the database model.
So at this point let's consider again the example case where in you Database Model you have those two entities - Customers and Orders. When a user log in into your application and wants to see his orders you need to join two tables in order to provide the front end the information that it needs. Option 1 - you don't have a Repository and you are using the DbContext directly from the method that returns the data. That means two things - you gonna have to write the same code everywhere you need to get this specific piece of information and 2 - if the business requirements change and in the same view that since now was used to show a customer and his orders now you have to show some additional info which is taken, let's say from a third table, then what happens - you have to go to each place where you use this view and change the way you retrieve the data. And option 2 - you have Repository, all your methods for accessing data are stored there and the Business Layer is completely ignorant about the way it get's the data, the Database Model is also ignorant about the needs of the business model which lead to loose coupling and only one place where you gonna have to make changes if you have to. In the scenario above, if you indeed use Repository and in your repository you have method called GetUserOrders() and inside this method you make the database call, the joins and so on, and all that the Business layer needs to do to get the data in the proper way is call this method when the requirements change and you have to include one more table, this time you don't have to look for all the places where you are using this data, you just have to modify one method and that's all.
It's pretty much the same logic on the way back. When you have some complex data returned from your front end and you want to save/update the old data with the new one, again - you can do it from the business layer but it leads to the same problem as when you have to get data, instead - you just pass the complex data to another Repository method which knows how to deal with it (say maybe some of the data should be saved directly into database and other should be used to feed a web service or whatever scenario comes to your mind) and here again - when something change, like - you want to use more heavily web services or the opposite, you want to migrate to more database centric design, all you have to do is change the method that takes care about the data the is concerned with this changes and nothing more.
So even though when I'm writing this I can see that DbContext can very well act as a repository and in this regard also as a data persistent layer, there are still some valid reason to not let this happen. Especially right now when the web services are more and more popular, WebAPI2 is out and RESTFull services are frequently used I think that leaving the EF as persistent ignorant as possible is the way to go.
But yet again, this is my opinion. There are a lot of articles on this topic so I urge you to google and read about it, since I think this is very important part form the architecture of every application.
P.S
In response to your comment which was written while I was writing my edited answer:
If I change data source I need to make changes in DAL anyway or in my example in repostitory. - the answer is yes. But there is no way tho change the data source without changing the DAL. The question is how easy will be to do that. I think the with what I've written already you can decide for yourself which way is better but just because I really think this is one of the few really strong arguments of leaving the EF persistent ignorant all write it again. When you have Repository and there are methods which take care for data manipulation, every time something related with the way the data is fetched affects only those methods and nothing else. If you use the context freely, in your business layer even a little change may cause you a lot of trouble just because it always possible to miss something, you have to go through the entire code to make sure that you have fixed all places and it's just not as efficient as having all in one place.

Form handler routes for image uploads

I have an edit page which is grows with the size of the app. We're now running in to a situation where the server side action (MVC) is handling image uploads and conversions alongside regular text saving to database.
What's the best way to make this more maintainable? Separate controller for images uploads, so that we create an writeable API? Or more actions within the same controller?
There are few ways, which could let you mitigate the problem with rising complexity :
Implement HMVC, where each controller calls sub-controllers. This would let you to split up the "update" tasks in logical and manageable chunks. Especially, if i am correct in thinking that there is more the one "update page". The HMVC structure would let you to assemble different update pages from existing fragments with quite minor additional hustle. Main disadvantage: relatively large change in architecture.
Split the update page(s) in smaller forms, each submitting to a different controllers action (or maybe a different controller altogether). Main disadvantage: user can update only one part at the time
Evolve the model layer, so that the API you use interacts with service layer instead of domain model layer. This will let you isolate the complexity of updated and provide a simpler interface to use in controller. This too would have the added benefit of composing update form(s) from manageable pieces. But i don't know the penalties that come with this approach .. never have used it myself.
The bottom line is: you will have to change one part of MVC. In your situation i would choose the HMVC way, but mostly because i am familiar with it, and multiform page might induce rage from users.

Options for Caching Generic Object Lists for iPhone?

I have an app that connects to an API and retrieves a large number of small objects at a time. These objects are returned from json-framework as a heirarchy of NSDictionary, NSArray, etc. They are basic data types, and the primary structure of most of the api calls is a list of items(which could be hundreds of items long).
I will be displaying the data in a UITableView, but I don't want all the data in memory(as I could potentially eat it all up). I also don't want to hit up the api for the objects again, as they can be cached for a few hours without any problems.
I have thought of a couple of solutions, but I am eager to hear other options. I have thought of using Core Data in various ways, but I'd like to avoid having to create and maintain entities for each type of entity returned from the API. Using Core Data like this seems like overkill. I could use core data to store archived objects, though I worry about the archiving/de-archiving overhead.
I really want a generic store that can keep a list of objects cached, and then be able to retrieve arbitrary items from the list.
The factors that I care about:
Ease of maintenence. If the api changes or we add other objects, I don't want to have a lot of places in the code to change. Storing generic objects(NSCoding compliant) is ideal.
Performance. Caching and retrieval will all be happening while the user is interacting with the app(in the background), but I don't want to consume too many resources to make the app feel slow.
Are there any existing libraries that already exist for this purpose? What options am I missing? Maybe convince me that creating Core Data entities for each data type is actually a good idea for an object cache.
In case you haven't tried out the facebook/Three20 library, they have implemented a disc/memory cache and have used it as one of the fundamental layers inside their network module. I used three20 in my app but I never used this cache layer directly, so I'm not sure about the performance with it. Still, it's a nice thing to keep in mind.
Besides, the Enormego team has implemented a stand-alone photo viewer thing. And inside this photo viewer there is a nicely-working disc-memory cache. I'm not sure whether it has anything to do with the three20 cache. But I do believe it can cache generic objects other than just images. You can try it out by yourself.

Is there any reason why someone would want to create an Core Data model programmatically?

I wonder in which cases it would be good to make an NSManagedObjectModel completely programmatically, with NSEntityDescription instances and all this stuff.
I'm that kind of person who prefers to code programmatically, rejecting Interface Builder. But when it comes to Core Data, I have a hard time figuring out why I should kill my time NOT using the nice Xcode Data Modeler tool.
And since data models are stuck to a given state (except when you want to do some ugly migration operations where thinks probably go wrong and users get mad, really mad), I see no big sense in a data model that's made programmatically for the purpose of changing it all the time.
Did I miss something?
I dont think you missed anything. The only reason I can see to create your model programatically would be if the objects you are modeling are themselves dynamic: you could for instance build a coredata entity (or graph of entities) in response to a web service which changed over time, or was selected by the user. However, I think if you had that or a similar use case, you wouldn't need to write this question (and you'd probably solve it a different way anyway)
So, if your application is dealing with resources that are dynamic, as #Andiih mentioned, then this programatic is the only way to do it. I don't know what my core data entities are until runtime, I don't know what the attributes are, or what the data looks like. So, I ask the server to give me the kinds of resources I should support and what their attributes look like. I build the model, the entities, the properties, the relationships - at runtime. I still want to use Core Data because I'm dealing with a lot of data and I need the benefit of efficient memory management with NSFetchedResultsController, etc. I can only do this programmatically.
The trouble is how to handle migration to try and preserve as much of the persistent store as possible, to reduce the size of the networked data payload after the model changes. Right now I blast the whole model and the persistent store if there's a conflict. I haven't yet figured out a way to create an .xcdatamodel from a programmatically generated model, thus I can't yet create a version mapping to do the migration.
Everything is a trade off. Basically, I think IB and the visual Core Data modeler are the right tool if you're building a simple application. You'll need to make the determination when your application becomes large/complex enough that you prefer to have direct control over all aspects of the code.
Regarding Interface Builder, if you have an application with a variety of complex interactions between view controllers, and multiple custom controls, I find code more appropriate.
For Core Data, the question is pretty much the same. Does your project have a defined scope? Can you foresee everything in that scope being done within the visual modeler? If so, it's probably fine. For other projects, where you may be asked to add features on an ongoing basis, perhaps it's better to spend a little more time writing it out so you have more flexibility later.
One other thing to consider, that doesn't get mentioned much, is it's MUCH harder to ask for help with IB or any hybrid visual design/code system. When something does go wrong, or you need help, it's way easier to post your code, than try to explain what's going on in a visual modeler.
In general, there's no reason to build the managed object model in code. There's nothing you can do in code that can't be done in the model editor. There are some fancy tricks you can do in code, however, to work with multiple models. For example, you can merge two models, establishing cross-model relationships between entities in those models at load time (see Cross-model relationships in NSManagedObjectModel from merged models?).
Regarding whether it's a good idea to code or use the graphical editor, I think the balance tips heavily towards the graphical editor in this case. Being able to verify the model by visual inspection instead of (rather convoluted) code is a win. The model can still be verified by unit test, if you desire.
I have one use case that might be valid, what if you load some data from the internet whether it is XML from an RSS Feed or WSDL response, then flatten those responses into a tabular from generating an in memory data table and finally mash it all up into a single coherent data model, then you can create the entities for those in memory data tables and create master/detail relationships. That's one case I think Core Data data model generated programmatically could become handy and a powerful feature.
I've changed models programmatically in unit tests. For example, I wrote a class that is designed to work with Core Data models that have a particular protocol attached. Instead of testing against a random implementation, I mutated the default model by adding one just in the unit tests programmatically, and tested against that test-only model.