I am starting a large WPF application which I will spice up with Caliburn.micro.
I have three views with corresponding viewmodels who all talk to the same instance of a model.
How can I pass the model to the viewmodels using Caliburn.micro?
The problem arises from the need for several viewmodels to access the same model instance.
It is essentially different parts of the model's functionality that is being split up into smaller parts (VM's and V's) because often not all of the model's functionality is needed.
Related
I could have a simple QVector, QList, etc. of QObject to present in ListView, GridView and TableView and add/edit/remove items in/from those View. To me using QVector, QList, etc. of QObject* is the easiest way to accomplish the ultimate goal. What's the real benefit of inheriting QAbstractTableModel, QAbstractListModel, etc.? In WPF we've VirtualizingStackPanel and some properties to boost performance in such type of View. Does inheriting those Abstract..Model serve the same purpose or either way (inheriting or using plain QVector/QList), performance will be same?
The advantages of QAbstractItemModel and subclasses are mainly increased performance when handling larger lists, and increased flexibility by using proxy models:
Partial updates: A model can tell the view that single rows or ranges of rows were inserted, moved, removed or updated which then the view can act upon in a smarter way than throwing away and rebuilding everything. The cost of inserting an item in the middle of 10k other items is cheap, for example.
Lower overhead: A large list of, say, 50k QObject*s would have a major overhead, both in cost for the objects themselves and in handling all the signal/slot connections for handling the property updates.
A model can act as an adapter to an already existing data structure, without the need to hold all the data in the model (although that can be tricky in practice, to guarantee correctness/consistency)
Lazy-loading: The model can load data on demand as the user is navigating the view, without having to have all data already available (see fetchMore()/canFetchMore()).
Flexibility through proxies: QAbstractProxyModel and subclasses (in particular, QSortFilterProxyModel) allow stacking of models to filter/sort/modify the data in the original model. With QSortFilterProxyModel sorting and filtering is usually much simpler to implement (and without changing the original data/model) than implementing it manually for a QList. Simple modifications like changing the returned data for a certain role can be implemented by subclassing QIdentityProxyModel.
More complex data structures: QAbstractItemModel also allows for trees (tricky to implement though) and tables. These are more often used in "traditional" (QWidget-based) desktop UIs than in embedded/mobile touch UIs though.
I'm reading up on the latest version of Qt, and it seems the Model/View/(Delegate) pattern is what's being pushed. It should be conceivable then to completely wire up the views without writing a single model, at least for the purpose of specing out how it looks. Is this the advised approach?
Also, where are the event wirings supposed to be placed? I assume that signals are coordinated by the MainWindow code?
You will need dummy models of course, made using existing Qt model classes. Looking at empty views is somewhat unhelpful, since you can't check out the primary delegates for the underlying model. Without any data, about the only delegates you can check out are the ones used in the headers, IIRC.
There are no event "wirings" on the view side of things, except for providing programmatic means of interacting with the view. The models may need a lot of interaction, depending on what's being modeled
Conceptually, you may have just one model that represents the data in your application, but it'd be a lot of spaghetti to expose various aspects of that model to the specialized views. You may then use view-models as adapters: they'd take the big model and expose a targeted slice of it, making it easier to consume by views. That's the pattern widely used in .net WPF.
Can you advice on structering the solution projects, files, fodlers in a way that it matches with the MVP design pattern in order to represent the pattern idea?
I mean how would you put your presenters, data acces layer, views etc.
Thanks
Solution architectures are generally pretty independent of which UI architecture you're using, although you might have some additional separation if you plan to have multiple UI applications (most projects don't).
I tend to start out with a template similar to this:
Acme.Sales or Acme.Sales.Core - internal domain/business logic
Acme.Sales.Entities - data entities used for persistence layers. Entities have similar class structure to the core (domain) model, but tend to have thinner logic, additional properties like Id, two-way relationships (as opposed to the one-way relationships in the domain model), and virtual members for the ORM to be able to override. This assembly will also normally include abstract repositories for CRUD operations on entities.
Acme.Sales.Entities.Impl where Impl is something like LinqToSql or NHibernate - this namespace defines one possible implementation for actually persisting the Entities. Concrete implementations of the abstract repositories go here.
Acme.Sales.UI contains common classes relating to any user interface - might be an MVP GUI or even a CLI. As with Entities, these are similar to the Core classes but tend to have presentation-specific logic and attributes, such as validation and formatting (which most often today is done through DataAnnotations). Note that the core library should also validate, but UI validation tends to be more about formatting and sanitization of inputs than business rules. It's tempting to mimic the domain's class structure here, but you'll have an easier time overall if you stick to flat, DTO-style classes for your UI model.
Acme.Sales.UI.Services contains abstract or concrete "service" types that are meant to interact with both the UI and the domain/persistence layers. Thus this project takes dependencies on Acme.Sales (domain), Acme.Sales.Entities (abstract repositories), as well as Acme.Sales.UI, and handles all of the mapping activities between those different layers.
Acme.Sales.UI.Impl where Impl here is something like Mvp, Mvc,Mvvm, and so on. You can drop the UI from this namespace if you want, as the implementation implies what it is. This generally takes a dependency on the UI project but adds those things specific to a particular UI model; controllers, presenters, view-models, etc. This is your actual "application". It's also where you normally choose an IoC container (AutoFac, Ninject, Spring.NET, Castle, Unity) and wire up all the specific implementations to the abstract types.
Within your application project you'd want to separate logical concepts into different sub-namespaces/folders. For example put your presenters in Presenters and views in Views - pretty straightforward - and create subdirectories in each of those if you start getting a really huge number of screens (e.g. Views.Billing and Views.Shipping). It's also OK to create top-level Area directories/namespaces here and put separate Presenters, Views, etc. in each one of those areas - this is the approach currently taken in ASP.NET MVC.
You don't need to separate Presenters and Views into different projects. Rest assured that the views which you tailor-made for MVP will be utterly useless for MVC or MVVM, and vice versa. The only part of a model-driven app that really stands a chance of being reused is the model itself.
Note that this is just a very basic architecture for an app with a single database and relatively simple domain logic. It doesn't include any higher-level back-end constructs like app integration (e.g. web services), eventing (pub/sub), batch processing, CQS, ad-hoc reporting, and so on and so forth. These tend to be pretty common in larger-scale business apps but if you're just starting out on a new social bookmarking app then you don't need any of that complexity.
Also note: This is all assuming you're planning at least a medium-size project - let's say one that you and/or your team will be working on for 6 months or more. If you plan to bang it all out in 1 month or less then please, don't waste your time on solution architectures at all. It's perfectly OK to just jam it all into one project and reuse the same classes for domain, entities, and UI - as long as the project is small enough to be easily understood and maintained. Carefully monitor the complexity and maintenance overhead and consider refactoring into the above structure over a longer period of time if the project starts turning into a ball of mud.
Below would be a nice start. You could split up even more if the project gets bigger:
Company.Project.Core -> Controller logic
Company.Project.Domain -> Domain models (view models and database models)
Company.Project.Interface -> Views, presenters
I have to admit I have been carrying the "Repository should not return IQueryable" banner because it is harder to test. I have been influenced by the answers to other questions like this and this.
This morning I've been reading ScuttGu's blog about ASP.NET vNext where he details Model Binding using a SelectMethod that seems to rely on IQueryable for paging and sorting.
Do you think this will force us to reconsider the role IQueryable plays in repositories?
DDD Repository should encapsulate data access technicalities:
Definition: A Repository is a mechanism for encapsulating storage,
retrieval, and search behavior which emulates a collection of objects.
It is also responsible for handling middle and end of life of domain objects. Repository interface belongs to Domain and should be based on Ubiquitous Language as much as possible. In addition to DDD book, these two articles cover almost everything you need to know when designing repositories:
How To Write A Repository
The Generic Repository
Exposing IQueryable on the Repository interface is not optimal in my opinion. IQueryable is not part of Ubiquitous Language. It is a technicality, it has no domain meaning. Instead of encapsulating data retrieval Repository would expose bare data access mechanism, which essentially defeats the purpose of having Repository in the first place.
Regarding ASP.NET. This is a UI framework. Why would you allow UI framework to affect the design of you domain model? Microsoft examples often times encourage things like UI data grid binded directly to your database tables. Or, most recently, controls binded to what is referred to as Domain Model, while it is in fact Anemic Model, or simply dumb data container with gets/sets. The quote from the article that you mention (I put some emphasis):
Model binding is a code-focused approach to data-binding. It allows
you to write CRUD helper methods within the code-behind file of your
page, and then easily wire them up to any server-controls within the
page. The server-controls will then take care of calling the methods
at the appropriate time in the page-lifecycle and data-bind the data.
My interpretation of this is to ditch the model and objects and just bind your data to UI. This is probably a valid and justified approach in a lot of cases. But since the question was tagged as DDD I would say that in DDD this is called Smart UI Anti-Pattern.
I have a ASP.NET MVC solution with three projects:
SquarkMVC
SquarkBLL
SquarkDAL
The SquarkDAL layer has Linq2SQL classes for each object in the DB. BLL references the DAL in order to conduct business logic on the DB.
My question is this... without having to reference the DAL in the MVC layer, how should I model the entities of the DB in the MVC layer? For instance, if I have a sign up form in the MVC layer, what is the best way to take that information, pass it to the Business Layer which then passes it on to the Data Layer? I don't want the MVC layer to know anything about the DAL.
I've found this answer on another post... is it generally agreed that the best way to overcome this is to create a transfer object in order to pass the information from the presentation layer, to the business layer, which will then convert the information into the entity classes used by the DAL?
Hope this makes sense.
Using objects is a common way to do this. Usually DTOs (Data Transfer Objects) are "dumb" POCOs having a set of properties, and acts like a "struct", but, if you put on them validation and more logic (view logic) you have a view model and you can use them to work with the controller. This one should use the model (of the Business Layer).
More, Business Layer should never having a reference to the DAL, because your business model should be independent by the storage.
Instead, the data access layer should reference the model, and choose the right way for persistence. You can achieve it with the Repository pattern.
Anyway there are a lot of books about domain driven design.