Are there any examples of using Autofac in a MVVM application? I'm not sure how one would control lifetimes and disposal of objects in a MVVM environment.
I understand I can create a lifetime and resolve from beneath it, but that really seems more like a service locator pattern than an IoC pattern.
I don't have a public example, but I have done this in Silverlight applications.
I used the Silverlight navigation framework to organize the top level of content. When the frame navigated to a new page, I created a lifetime scope in which I resolved the page's root view model, which I associated with the page through an attribute:
[ViewModel(typeof(OrdersViewModel))]
public class OrdersView : Page
When the frame navigated to a different page, I disposed the lifetime scope before creating the next one.
The same pattern applies to opening dialogs. Each dialog gets its own lifetime scope and view model. When it closes, the lifetime scope gets disposed.
There are also situations which don't fall neatly along these boundaries. Sometimes you need more granularity and can go deeper into lifetime scopes using contextual scopes. These situations are usually one-offs and involve some glue to begin the lifetime scopes.
I find it helpful to think in terms of units of work: you commit changes at the end of each lifetime scope. This makes the extent of a set of data a natural lifetime scope.
Related
I've set up a very simple (Universal Windows) App in C++/WinRT.
It's just App <- MainPage <- DataViewModel <- Data for now.
MainPage has some Sliders etc. which are bound (x:Bind) to DataViewModel, which contains an instance of Data. Working fine so far.
However, the Data is a member of DataViewModel. This seems to be an obvious code smell. Data should not be "owned" by the GUI. All Examples/Samples I've come across seem to be set up like this, though.
I also want to run a background thread (pure C++ code) that works with one and the same instance of Data.
The question: Who "owns" Data. How do I connect things? How to pass the reference?
My best idea so far: The App class itself should just own the one instance of Data. The MainPage ctor should take a Data& and pass it on to the ctor of DataViewModel. However, I don't seem to be able to write a custom ctor for MainPage, because there's generated code involved.
Just pointing me to well coded Sample App would also be appreciated.
IInspectable (in the comment above) makes a noteworthy point: "Ownership really only matters when non-static lifetimes are involved. If Data represents data with static lifetime then there's nothing inherently wrong with exposing it through a static App class member."
In this vein, don't limit your thinking of Data (i.e., the model) to just object(s) which some other object owns. The model should be thought of as a wholly independent component.
Let me approach this notion from another angle. Most people will readily describe MVVM as three independent "layers" or "components" or what have you, wherein the model "doesn't care" about the view model, which in turn "doesn't care" about the view.** In code (as you have seen yourself), you're probably going to find some clear cut ownership patterns to reflect that basic premise. For example, if we're following the the "view-first" approach like the Microsoft samples, you'll start with your App object, which owns an instance of a view object, which in turn instantiates a view model instance.
But the key to MVVM is not who owns whom, it's the relationships between those layers. If you wanted to, you could write a program where, say, the views and view models were all static members of the App class and still have a (conceptually) textbook MVVM structure once everything is hooked up. From that perspective, it doesn't matter where ownership resides.
Now, the thing about Microsoft samples like the Photo Editor is that ultimately they're just demonstrations of how things can work, not a treatise on design patterns. Consider when your data is coming from a database or a web service. Where do you draw the conceptual line between model and view model? The question may sound pedantic, but the way you evaluate these things influences your design decisions.
Which brings me back to your specific question. If it seems like code smell to you when examples you find online stick the model data any old place, you're not wrong. In "real life," the model can be an entire API, not just one illustrative class. You'll potentially have an elaborate subsystem delivering data to you that depends on services completely separate from your application. Or it might be an opaque third-party API that you're calling into via global functions, etc. Just remember that the key isn't "ownership," it's (the conceptual) "relationship." ***
** As a side note, you mention Data being a member of DataViewModel and describe this as Data being "'owned' by the GUI." Ideally, the view model should have no inherent ties to the UI, just application logic. Don't think of it as an extension of UI functionality.
*** But please don't take this post to imply that the actual implementation of the MVVM paradigm isn't important. That's true of any design pattern. The exact form that implementation takes depends on the specific application and whatever your boss wants you to do. All I'm saying is, don't get hung up on ownership. :)
From what I understand about the flutter package, Provider, is that it's a way to share objects between widgets. I know another way of doing this is to create a class, say AppGlobal, and define various static variables that the whole app could use. It's suggested that Provider is a better way of doing that, but I don't understand why that is.
An answer to the question should take different aspects into account:
Testability - not much of a difference. Both cases require code
change to replace either the singleton itself or the "provided
singleton"
Code Coupling - not much of a difference either (see comment on
testability)
Scoping - Singletons most often live through the lifecycle of the whole
application. It would be error prone to manage a singleton for some
widget subtree. Here provider definitely has its strengths by taking care of
creation and disposal.
UI updating - when using singletons this must be completely hand coded with
setState which will produce lots of error prone boilerplate code.
Provider provides this already under the hood.
Listeners - changing state in one part of the application should
notify all consumers of that state. With singletons this has to be built by hand.
Provider provides this already under the hood.
Lazy Loading - By default, values are lazy-loaded, which means they are called the first time the value is read instead of the first time the provider is created. This can be disabled by lazy: false
Hope this answers the question in more depth.
A quick search through the web and it seems like a global instance of a variable is not the best idea since it is not testable, and it makes the code very coupled with the AppGlobal class.
Here is a link that describes what I am talking about and it does a great job with examples.
Global Access vs Scoped Access with Provider
I have read a lot of gwt-mvp questions that are asked here, but since i'm totally new to this design pattern I would like to ask some questions:
[1] The Activity-Place pattern is a different pattern than mvp?
[2] In the MVP pattern presenters contain the logic. Now the logic of the widgets/controls is defined in the Activities?
[3] The CustomPlace classes are fixed (as the Eclipse plugin constructs them) or can i put data/methods and what kind?
[4] What is the use of the Presenter interface inside a CustomView? What data/methods would make sense to add into it?
[5] I want to build an application that will use many data structures that will be saved into a database. I have read some other posts here and I will make the Model part of MVP live inside each Activity. So i think to create each time the data structures of each activity at start and load its values (if necessary from db) and will update the database after the user goes to another view. What do you think about this approach?
Let's start by debunking one myth: Activities/Places have nothing to do with MVP. Places is about navigation, Activities are about "componentizing" the UI wrt Places. On the other hand, MVP is a design pattern, it's about how to organize your code.
Many people are using their activities as their MVP-presenters, but it's not enforced. The GWT team is trying a new approach where the activity is distinct from the presenter (work underway in the mobilewebapp sample if you want to follow what's going on there). You could also have your activity being your view and making use of an "internal" presenter (similar to how Cell widgets work)
A Place is more or less a URL. You can put whatever you want in it. I'd suggest making places immutable though: build a Place, goTo it, make use of its properties to build your UI.
That's about MVP then. This is only needed to decouple your view and presenter, mostly to make mocking in unit tests easier (this is particularly of the view interface though, not much for the presenter one, unless writing a test harness for you views). In some cases, you might also want to use the same view with distinct presenters; they'll all implement the same interface so the view can talk back to them.
How about the closing of the window/tab? I'd rather use a periodic auto-save, or an explicit save button; and implement mayStop so it prompts the user when there are unsaved changes (similar to how most desktop office apps work —e.g. MS Word or LibreOffice—, and GMail if you try to navigate away before your mail draft is auto-saved)
The Activity-Place is an implementation of the pattern. Google introduced gwt-mvp pattern at Google IO, but only provided it's implementation as part of GWT about a year later.
Yes Activities contain business logic. No, widgets/controls usually do not contain any logic, they just fire events based on user action. The logic that acts upon those events is written by user and resides elsewhere.
I don't use Eclipse, so wouldn't know about Places generated by it. Normally custom Places can contain custom fields and methods. For example they can contain custom place token arguments, i.e. if place token is "#place:id1", than your custom Place could contain field holding this argument.
When View needs to call/access Activity, it does so via Presenter, which Activity implements. For example when user enters all data in a for and presses submit, then you could have a method in Presenter named submit(formData).
Preparing/loading data in activity.start(..) is a normal way of doing things. If particular activity is used a lot, then you might consider caching the data if appropriate.
I am developing a WPF desktop app that uses Entity Framework 4 and SQL Compact 4. I have seen two distinct styles of Repository classes:
The Repository instantiates an ObjectContext, which is disposed of when the Repository is garbage-collected. The lifetime of the ObjectContext is the same as the lifetime of the application.
A separate DataStoreManager class creates and holds an ObjectContext for the life of the application. When a repository is needed, a command gets an ObjectContext reference from the DataStoreManager and passes it to the constructor for the New Repository. The lifetime of the ObjectContext is the lifetime of the application.
Is either approach considered a bad practice? Does either present any absolute advantages over the other? Is either approach considered best practice? Is either more widely accepted or used by developers than the other? Thanks for your help.
I would have thought that holding an ObjectContext open over multiple accesses would be bad practice. As soon as it becomes corrupted then you would need to recycle in and handle the corruption.
The Repository pattern is more for abstraction of data access but doesn't necessarily map to lifetime of context.
The unit of work pattern is more about encapsulation of one or more database/repository accesses i.e. a use case may have you adding a new Blog and then adding the first default post, this may require calling two repositories, at this point you might want to share the context and encapsulate these two commands in a transaction. Adding a second post might be done hours later and be a new context/unit of work.
DJ is right in mentioning Context lifetimes which you'd set generally at an application level.
The best practice is depended on how your users are going to use the application:
And how your application is structured.
if there is only one user using your application at one time, you can even create your entity context as a static instance.
context can be used per request, per thread, per form.
read more: http://blogs.microsoft.co.il/blogs/gilf/archive/2010/02/07/entity-framework-context-lifetime-best-practices.aspx
I heard a bit about we should keep the code in controllers as less as possible. So where do we put those code?
This will depend on what code you are talking about. For example if you are talking about validation, this should go into the model, if you are talking about data access this should also go into a repository or the model (personally I prefer repository), if you are talking about a business logic this should go into a service, so that all that's left into the controller is to call this thing and pass the result to the view.
I would recommend you watching this video presentation about how to put your controllers on a diet from Jimmy Bogard.
Do you know thin and skinny controller? So my answer is if you put many line of codes in controller, your code will be messy and hard to unit testing. Really the controller only executing the actions related with current HttpContext, so if you have business logic, data access, encryption,... you must separation of concern. The reason you don't put business logic at here is business belong to domain. So delegate to Domain for processing. Controller must be consider all actions related to HttpContext (Session, ViewData, TempData, User in current thread, Global and Local Resources,... ) and delegated all other actions to other component. Rule of thumb is fat model and thin controller for cook delicious cake(phpcake).
Some links you can reference for skinny and fat Controller at here and here.