I´m developping a project using WPF + MVVM.
The program needs to load objects (cases) from a repository and allow the user to edit it.
The main functionalities are:
CRUD of cases
Know which cases have been loaded
Know which case is currently selected
Currently, the version 0.1 uses a singleton class Session (in namespace model) to store a list from all cases loaded.
There is also a "Case Management" service that perform several operations in the Session singleton:
Load a case from the repository and store it in Session
Remove cases
Verify if a case is valid
Select a case for editing
I´m new to WPF, and I would like to know if there is a design pattern that is suitable for this situation. I´m afraid that I´m not going to the right direction.
I dont know if I have provided all information needed, but I´m willing to answer any question as fast as I can.
Your design is fine, i can't see anything wrong.
I would suggest one thing though, get rid of that singleton session object and use dependency injection, and let the DI container decide what life strategy to use for the Session object at the application composition root.
I hope your case management service is using some kind of ORM . If yes, then it will automatically take care of your Load Case/ Return Case and storing it into the session. And depending on user input when you want to get something from the session and you can use Dependency Injection principle (i would suggest to use Ninject) and achieve it with a singleton pattern .
Related
I have a web application developed with JSF 2 and primefaces. The project has been frozen for months, but it's quite advanced, the whole application run inside the same container under glassfish, so it's a monolith.
My application has an user interface and its purpose is to offer them the possibility to organize urls to tutorials (any kinds) as cards, with tags for the classification, into folders. So any user has its own tree, they can make a research inside the other users's tree create a link on a file in their own tree, copy a entire folder, reorganize it etc.
Nowedays we hear a lot about microservices, Spring boot, Angular Js, react etc. I like to develop with JSF it's a great framework, but I'm asking myself about refactoring my application, at least the necessary parts into microservices, and if JSF is appropriate for that or if I should user other tools.
What I like for example with JSF is the facility to create views, its component approach, and how it handle the full cycle of a request.
For example with a simple folder creation form :
I have to choose the parent folder, so I can bind a research component to a backing bean that makes a research indirectly in my DB using a DAO ( in my app an EJB using JPA). That happens at the "invoke application" phase and refresh my form list with ajax at the end. When I submit the form I can also bind a converter to the research component to retrieve directly a Folder object, the converter uses also a DAO to retrieve the object that I need at the "Invoke application" phase to finish the job.
I also use validators to control different attributes of a new folder, usually I declare them inside my entity class (Folder, User ...) with annotations like #NotNull etc. Before I save the folder on my db, I also check the user rights to see if he can write inside the parent folder and so on. I do that inside the backing bean, so at the 'invoke application' phase, and return a faces message if anything happens wrong.
When I read about micro-services I see that you can use them directly inside a form using json for communication, so it seems quite different. For example if I have a micro-service for the CRUD operations of my folders, are the validators, the converters, part of the service or are they stand alone services ? And what about the security checks ? that kind of architecture is quite mysterious to me.
ps : English is not my mother tongue so be indulgent please :)
AngularJs is pretty ancient man :)
You have to look at the pain points to identify ways to tear down your monolith. Monolith pains are usually slow and painful dev cycle and difficult manual test phases. If you did the entire arquillian thing and have full continuouos integration with single button deployments, you've slain the beast the hard way. Not many braved this route. But if you're looking at mounting feature creep with code freezes and manual test cycles then yeah you kind of want to try to pull some of those features out into a service you can redeploy very quickly
I'm working on a 2-tier WPF/EF Code First application. I did a lot of googling but couldn't find a sample implementation of what I was looking for... was hoping that someone on this forum could help me out. Here are the requirements:
On Application Start up
Open a DBContext
Cache the reference data in various maps/lists when the application starts
Close Context.
When user opens a form
Open a DBContext (I'm using UnitOfWork pattern here)
Fetch a fresh copy of Entity from context for Editing.
Call SaveChanges() when Save button is hit.
Close the Context.
The problem manifests when I use an object from Cache to change a navigation property.
e.g. use a drop down (backed by cache which was created using a different DBContext) to set Department navigation property.
The UnitOfWork either throws an exception saying entity was loaded in another DBContext (When Department is lazy loaded DynamicProxy) or inserts a new row in Department table.
I couldn't find even a single example where reference data was being cached... I can't believe that no one came across this issue. Either I'm not looking in the right place or not using the right keywords.
I hope this is doable using EF. I'd appreciate if you can share your experiences or post some references.
I'm kinda new to this so would like to avoid using too many frameworks and just stick to POCO with WPF/EF stack.
Try to attach your cached item (probably, you'd make a clone before attaching):
var existingUnicorn = GetMyExistingUnicorn();
using (var context = new UnicornsContext())
{
context.Unicorns.Attach(existingUnicorn);
context.SaveChanges();
}
Refer to Using DbContext... article.
You mention you are using WPF for this, in that case you don't necessarily have to open a new DBContext every time you want to interact with the domain layer. (Apologies if this goes against UoW that you are keen on using)
Personally I have been using code-first development for a desktop application, and I have found that pooling the contexts (and therefore the connection) prevents this problem, and hasn't led to any problems thus far.
In principle, as soon as the application is launched, a main Context object is opened for the main UI thread, and stays open throughout the duration of the application lifetime. It is stored statically, and is retrieved by any Repository class when they are used.
For multi-threading scenarios, any background threads are free to open up additional contexts and use them in Repositories to prevent any race conditions.
If you were to adopt this approach, you would find that as all repositories share the same context, there are no issues arising from object context tracking.
I ended up defining int foreign key property in addition to navigation.
In my application I only modify the int property and use the navigation property for displaying the details (read only controls).
While this works it makes the application a little fragile and sometimes inconsistent.
although this blog claims that the FK & Navi properties are synced by EF but I couldn't get it to work.
http://coding.abel.nu/2012/03/ef-code-first-navigation-properties-and-foreign-keys
I have a class running in a winforms app which uses EF Code First. The DbContext is created via DI through the class constructor. All works well.
The problem is the data being referenced is also being modified via a web site, using the same DI pattern with EF Code First, and the data changes are not being reflected in the context instance in the winforms app.
I can solve this by recreating the DbContext object in winforms every time I access it, but seems to be more of a service location pattern to me?
Is there a true DI technique to achieve this?
Or should I remove the context from the DI and use service location?
Were you not happy with the answer to your other question (http://stackoverflow.com/questions/7657643/how-to-force-ef-code-first-to-query-the-database) which suggested using Detach, AsNoTracking or Overwrite Changes?
1) Maybe you could pass an interface that has the ability to create a DbContext, instead of the context itself.
using(var context = _contextFactory.Create()) {
var entity = from table in context.Blah...;
}
The Create method could either create the concrete class itself (defeating the DI pattern a bit), or use service location to have one created for it. Not that nice, but it's better than embedding service location calls everywhere and still means you're controlling the lifecycle yourself.
2) Change the WinForm to read from a webservice run by the website, effectively similar to disabling caching.
3) Deep in the heart of MVC (well not really that deep) it is referencing the DI container directly and using it as a service locator to pass as arguments for newly created objects. Technically you could do something similar in WinForms, but it would need you to split your application up into little chunks (controllers) that don't have a very long lifetime. Maybe it's worth looking at some MVC/MVP frameworks for WinForms, although I found myself cringing at most I saw after a quick google.
The problem is the data being referenced is also being modified via a web site, using the same DI pattern with EF Code First, and the data changes are not being reflected in the context instance in the winforms app.
This is a problem with your expectations.
If your web service and window forms app are in separate processes, they won't share in-memory data.
If you want to sync their in-memory data, simply re-query in one context after committing to the database in the other. This is the same as trying to share data between different SQL connections.
I can solve this by recreating the DbContext object in winforms every time I access it, but seems to be more of a service location pattern to me?
If you want to recreate the DbContext repeatedly, you could use an abstract factory to allow manual re-creation of the object, yet allow you to inject the specific implementation into the factory.
This is not (necessarily) the Service Locator pattern, and you would have to ensure that you manually dispose your DbContext instances. I'd give you some example code, but different DI containers have totally different ways of accomplishing a factory pattern.
Or you could simply make sure that you commit your data on the web service side, and re-query the data on the WinForms app side.
I'm developing a CakePHP application that we will provide as a white label for people to implement for their own companies, and they'll need to have certain customization capabilities for themselves.
For starters, they'll be able to do anything they want with the views, and they can add their own Controllers/Models if they need to add completely new stuff. However, I'd rather advise against touching my controllers and models, to make version upgrading easier.
Esentially, the customization capabilities I'm planning to give them are going to be quite basic, I just need to call "something" when certain things happen, so they can do things like update external systems, e-mail themselves/the clients, things like that.
I'm wondering what's the best way to do this?
My plan is to have a "file" (with one class) for each controller of mine, to keep things reasonably organized. This file will have a bunch of empty methods that my code will call, and they'll be able to add code inside those methods to do whatever they need to do.
The specific question is, should this class full of empty methods be a Component? A Controller? Just a regular plain PHP class?
I'll need to call methods in this class from my Controllers, so I'm guessing making it a Controller is out of the question (unless maybe it's a controller that inherits from mine? or mine inherits from theirs, probably).
Also, I'd need the implementer of these methods to have access to my Models and Components, although I'm ok with making them use App::Import, I don't need to have the magic $this->ModelName members set.
Also, does this file I create (etiher Component or Controller) have to live in the app folder next to the other (my) controllers/components? Or can I throw it somewhere separate like the vendors folder?
Have you done something like this before?
Any tips/advice/pitfalls to avoid will be more than welcome.
I know this is kind of subjective, I'm looking to hear from your experience mostly, if you've done this before.
Thanks!
Two ideas that spring to mind:
create abstract templates (controllers, models, whatever necessary) that your clients can extend
write your controllers/components/models as a plugin within their own namespace
Ultimately you seem to want to provide an "enhanced" Cake framework, that your clients still have to write their own Cake code in (I don't know how this goes together with your idea of "basic customization capabilities" though). As such, you should write your code in as much an "optional" manner as possible (namespaced plugins, components, AppModel enhancements, extra libs) and provide documentation on how to use these to help your clients speed up their work.
I would setup a common set of events and use something like the linked to event system to handle this.
That lets the clients manage the event handler classes (read the readme to see what I mean) and subscribe to and broadcast events application-wide.
Also - if you want to have your users not muck about with your core functionality I recommend you package your main app as a plugin.
http://github.com/m3nt0r/eventful-cakephp
I am writing an app that listens on a network connection, and when some data arrive, it replies back, and depending on incoming data, it may need to ask user (show dialog) before replying back.
I don't know how to do this cleanly in M-V-VM architecture: the events and binding to observable collections are nice if I need to just update GUI based on incoming data, but what if I actually need an anwer from user before replying back?
And to make things worse, I want to do it synchronously, because I want my reply algorithm to be at one place, not partitioned into multiple callbacks with unclear 'who-calls-who' responsibilities.
Simply, something like
HandleMessage(Message msg){
string reply;
if (msg.type == 1) {
reply = ...
} else {
string question = msg...
reply = ShowModalDialog(question); // MVVM violation!
}
sender.Send(reply);
}
but I don't want to call view or viewmodel from model, as model needs to be reusable and testable - I don't want popping dialogs in every test run, and it would be violation of MVVM! No events (they are just one-way as far as i know, and have no backwards channel to get reply to event origin) or databinding, as it would be asynchronous.
Is this doable? This is a question I asked several test driven development propagators, and so far, I didn't get practically usable answer. Yet, a need for some additional input in the middle of processing is fairly common.
Thanks!
EDIT: this is application logic, so it clearly belongs to model, and even if in this case it didn't, I'd like to know the solution for cases when I really need user's input in the middle of business logic routine in model.
This is one of those problems that MVVM doesn't solve on it's own. One solution would be to use a service to query the user and then have the ViewModel use that service.
In my project we're using PRISM which besides providing a services framework also provides other tools for making GUI development easier.
Here's a writeup of how services work in PRISM.
So specifically in your case I would create some sort of IOC, register a query service with it, then in the ViewModel pass in the IOC and then use the IOC to get the query service, and use that to query the user. More work? Sure. But it means you can replace the query service with another implementation for testing by simply replacing it in the IOC.
MVVM + Services = Ultimate Power!
I don't know if this idea is in strict keeping with the tenets of MVVM, but...I would encapsulate the dialog functionality as a service (referenced via an interface). The implementation of the service would be in the UI layer, but for testing purposes you would just "mock" the interface.
Actually, it doesn't ALL belong in the application logic.
It seems like you have 2 different "views". There is the initial one (data coming in over the net), and a second one (confirmation dialog).
The model needs to determine that a new view needs to be displayed, signal the view to display it, then later respond to the input from that view.
Don't try to do it all in one step.