Is it appropriate to use a ReactiveCollection in an API? - system.reactive

Is it appropriate to expose a ReactiveCollection in an API? Specifically, in a service class that would be used internally on multiple applications. But as a thought experiment, we can also consider in public use as well.
I've been investigating Rx and ReactiveUI, and these seem like powerful tools. However, I don't have enough experience with them to determine if it is a good idea to require others to take a dependency on them.
More details:
I'm creating a tracking service class that would track connected clients. From my view, all that would be necessary for consumers to use this class is to expose an observable collection (possibly a ReactiveCollection) that exposes the connected clients, and notifies of changes to the collection which are managed by the service. The entitity representing the connected clients would also take advantage of INotifyPropertyChanged to notify of updates to the clients' state.

Since ReactiveCollection is a derivative of .NET's ObservableCollection (i.e. the non-Rx WPF/SL one), you could expose it as an ObservableCollection instead.

Related

Managing UI requirements in a microservice architecture

We have different client applications (each is built with a different UI and is targeted to a different sales channels) that are used to capture orders that ultimately need to be processed by our factory.
At first we decided to offer a single "order" microservice that would be used by all these client applications for business rules execution and data storage. This microservice will also trigger our backoffice processes such as client profile update, order analysis, documents storage to our electronic vault, invoicing, communications, etc.
The challenge we are facing is that these client applications are developed by teams that are external to ours (we are a backoffice team only). Each team responsible to develop a client application will be able to offer a different UX to their users (some will allow to save orders in an incomplete state, some wil allow to capture data using a specific worflow, some will use text fields instead of listboxes for some values, etc.).
This diversity of behaviors from client applications is an issue because our microservice logic will become very complex to be able to support all those UI requirements. Moreover, everytime a change will be made to one of the client applications, we will have to modify our microservice which is a case of strong coupling.
My questions are: What would be your best advice to manage this issue? Should we let each application capture the data the way it wants (and persist it if needed in its own database) and let them call our microservice only when an order is complete and compliant to our API contract?
Should we keep our idea of having a single "order" microservice for everyone and force each client application to capture the data the same way?
Any other option?
We want to reduce the duplication of data and business rules in our ecosystem but in the same time we don't want our 'order' microservice to become a mess.
Many thanks for your help.
Moreover, everytime a change will be made to one of the client applications, we will have to modify our microservice which is a case of strong coupling.
This rings alarm bells for me. A change to a UI shouldn't require a change to a backend service. (The exception would be if a new feature were being added to a system and the backend service needed to play a part in supporting that feature, but I wouldn't just call that a change to a client.) As you have said, it's strong coupling, and that's something to be avoided in a microservices environment.
Ideally, your service should provide a generic, programmatic API that is flexible enough to support multiple UIs (or other non-UI applications) without having any knowledge of how the UIs work.
It sounds like you have some decisions to make about what responsibilities your service will and won't take on:
Does it make more sense for your generic orders service to facilitate the storage/retrieval/completion of incomplete orders, or to force its clients to manage this somewhere else?
Does it make more sense for your generic service to provide facilities to assist in the tracking of workflows, or to force the UIs that need that functionality to find it elsewhere?
For clients that want to show list boxes, does it make sense for your generic orders service to provide APIs that aid in populating those boxes?
Should we let each application capture the data the way it wants (and persist it if needed in its own database) and let them call our microservice only when an order is complete and compliant to our API contract?
It really depends on whether you think that's the most sensible way for your service to behave. Something that will play into that will be how similar or dissimilar the needs of each UI is. If 4 out of 5 UIs have the same needs, it could well make sense to support that generically in your service. If every single UI behaves differently to the others, putting that functionality in your generic orders service would amount to storing frontend code somewhere that it doesn't belong.
It seems like there might also be some organisational considerations to these decisions. If the teams using your service are only frontend teams (i.e. without capacity/skills to build backend services), then someone will still have to build the backend functionality they require.
Should we keep our idea of having a single "order" microservice for everyone and force each client application to capture the data the same way?
Yes to the idea of having a single order service with a generic interface for everyone. With regards to forcing client applications to capture data a certain way, your API will only dictate what they need to do to create an order. You can't (and shouldn't) force anything on them about the way they capture the data before calling your service. They can do it however they like. The questions are really around whether your service supports various models of capture or pushes that responsibility back to the frontend.
What would be your best advice to manage this issue?
Collaborate with the teams that will use the service. Gather as much information as you can about the use cases in which they intend to use it. Discover what is common for the majority and choose what of that you will support. Create a semi-formal spec (e.g. well-documented Open API), share it with the client teams, ask for feedback, and iterate. For the parts of the UIs that aren't common across clients, strongly consider telling those teams they'll need to support those elements of their design themselves, especially if they represent significant work on your end.

Access to Prism Xamarin Forms injects outside viewmodels

I am currently developing a Xamarin Forms app and am in the process of reworking it to work with Prism. I'm really trying to adhere to MVVM design patterns (I'm trying to grow as an amateur developer and learn how to use them).
1) Is it improper from a MVVM design pattern perspective to utilize messaging services (Prism's EventAggregator) and UI interactions (Prism's PageDialogService) outside of VMs? I've written several "services" that are called from the VM and have found a need to access both messaging and UI services. As one example, The VM calls a service, the service retrieves and processes some data, ask a question to the user based upon those calculations and then continue to finish processing returning the desired value. To be proper, should control be returned back to the VM to "just" ask the question?
2) If it's not verboten, is it possible to access the services outside of VMs? It does not readily appear to me that I can inject them into the constructor of the service. Is it okay to "pass" them into the service's function I'm calling along with other parameters? That just seems un... MVVM-ish?
Update:
I'm not sure all my steps were necessary, but with the help below I got it working. First I converted my singleton service into an interface (IMyService) and an implementing class (MyService). Next, I overrode ConfigureContainer in App.xaml.cs and called Container.RegisterType<IMyService, MyService>(new ContainerControlledLifetimeManager());
I could then inject IMyService, just like IEventAggregator and IPageDialogService into my ViewModels and I could also inject those services into the public constructor of my implementing class (MyService).
ad 1) the event aggregator is meant primarily for UI, but you can use it as message bus in other parts of the app, too, if you don't need the more advanced features of a "real" message bus.
ad 2) unity will happily inject dependencies into services that are themselves dependencies of view models or other services. That's what a dependency injection container does :-)

Caliburn.Micro, MVVM and Business layer

I'm building a WPF application using MVVM pattern, and Caliburn.Micro is the framework choice to boost up the development.
Different from a conventional MVVM-based application, I add a business layer (BL) below the ViewModel (VM) layer to handle logic for specific business cases. VM is left with data binding and simple conversion/presentation logic. Below BL is an extra Data Access layer (DAL) that encapsulates the Data model (DM) underneath built with Entity Framework.
I'm pretty new to both WPF, MVVM and, of course, know almost nothing about Caliburn. I have read plenty of questions and answers about the Caliburn usage and now trying to use what I've learnt so far in my application.
My questions are:
Does it sound okay with the above layered architecture?
In the application bootstrapper, is it correct that we can register all services that will later be used (like EventAgreggator (EA), WindowManager or extra security and validation services), and also all the concerned VMs? These should be injected into VM instances via constructors or so (supposed I'll be using SimpleContainer). So from any VM that are properly designed and instantiated, we can have these services ready to be used. If I understand correctly, Caliburn and its IoC maintain a kind of global state so that different VMs can use and share it.
Navigation: I know this topic has been discussed so many times. But just to be sure I'm doing the right way: There'd be a ShellViewModel acting as the main window for the whole application with different VMs (or screens) loaded dynamically. Each VM can inherit either Screen or ViewModelBase or NotifyChangedBase. When I'm in, let's say, VM A and want to switch to VM B. I'd from inside VM A send a message (using EA) to the ShellViewModel, saying that I want to change to B. ShellViewModel receives the message and reloads its CurrentViewModel property. What should be a proper data structure to maintain the list of VMs to be loaded? How can stuffs like Conductor or WindowManger come into the place?
Can/Should Caliburn in one way or another support the access to the database (via EF). Or this access should be exposed to VM and/or BL only?
Thanks a lot!
Different from a conventional MVVM-based application, I add a business layer (BL) below the ViewModel (VM) layer
That's the standard case. ViewModels can't/shouldn't contain business logic which is considered to be part of the Model (Model in MVVM is considered a layer, not an object or data structure) in the MVVM. ViewModel is for presentation logic only.
Yes, as long as your Business (Domain) Layer has no dependency on the DAL (no reference to it's assembly). Repository interfaces should be defined in the Business Layer, their implementations in the Data Access Layer.
Yes, Bootstrapper is where you build your object graph (configuration the IoC container).
Registering ViewModels: Depends on IoC framework. Some frameworks let you resolve unregistered types, as long as they are not abstract or interfaces (i.e. Unity). Not sure about Caliburn, haven't used it. If the IoC supports it, you don't need to register them.
One possible way to do it. I prefer navigation services though, works better for passing around parameters to views and windows that are not yet instantiated and you always know there is exactly one objects handling it.
With messages, there could be 0, 1 or many objects listening to it. Up to you
What do you mean with support access to the database? You can use it to inject your repositories and/or services into your ViewModels, other than that there isn't much DB related stuff to it.

What is best practice to communicate between React components and services?

Instead of using flux/redux architecture, how react components should communicate with services?
For example:
There is a container having few representational (react) components:
ChatBox - enables to read/write messages
AvatarBox with password changer - which enables to change user's password
News stream - lists news and apply filter to them
Thinking of them as resources representation, I want each of them to access Microservice API by itself (getting or updating data). Is this correct?
It will provide clean responsibility managing models, but it gives performance doubts using http requests to load each component's content
This question also reffers to: How to execute efficient communication for multiple (micro)services?
When you opt for not using Flux/Redux, here is what you do:
Create an outer component that should wrap all the other components. This component is also known as a higher order component or a controller view. This component should use an HTTP library to communicate with your microservices (I personally like Axios). I would recommend that you create a client API object that wraps Axios. Your higher order component can reference this client API so it is agnostic of the HTTP library and whatnots. I would also put a reference of this client API on the window object in dev mode so you can do window.clientApi.fetchSomething() in the Chrome console and make debugging easier.
Make all the other components (ChatBox, AvatarBox and NewsStream) controlled. If you are not familiar with this concept, it means they receive everything they need through props and they avoid keeping state. These components should not call the microservices themselves. This is responsability of the higher order component. In order to be interactive, these components should receive event handlers as functions as props.
Is this correct? It will provide clean responsibility managing models, but it gives performance doubts using http requests to load each component's content
You can avoid performance issues by not allowing each component to directly contact the microservices. If your higher order component compiles all the information needed and make as little as possible HTTP calls, you should be perfectly fine with this approach.
It's generally recommended to use Flux/Redux, but if you opt out, this is how to go about it.
According to: https://facebook.github.io/flux/docs/overview.html#content
Occasionally we may need to add additional controller-views deeper in the
hierarchy to keep components simple. This might help us to better encapsulate a
section of the hierarchy related to a specific data domain.
And this is what I am thinking about responsibility of particulary component's domain (three of them was described). So could it be reliable to make three controller views (or stores) that can access dependent API to manage resource's data?

Services in Domain Driven Desing

I am bit confused about services in DDD.
First of all. Why are services always expressed as an Interface? Is that a rule?
Why do services contain only one method? Sometimes it makes sense to implement related methods in a single class.
Do I have to make services for each repository? I must be doing something wrong because I find myself making services for CRUD operations.
For example I have a repository with the usual methods. How do I control the access to the objects persisted in the repository? I tend to make services with lots of reading methods. Those services can check the user roles and then decide if the user can use the objects or not. I feel something is not good in my design.
I'm assuming you're talking about domain services. There are other types of services in DDD such as application services and infrastructure services.
First of all. Why are services always expressed as an Interface? Is
that a rule?
No this is not a rule. Only create an interface abstraction when there is a need for it.
Why do services contain only one method? Sometimes it makes sense to
implement related methods in a single class.
A service with a single method can be thought of as implementing a single operation - a single use case. If it makes sense to encapsulate multiple operations in a single object than this is also acceptable. However, conflating multiple responsibilities into a single class often leads to violation of SRP.
Do I have to make services for each repository?
No. A repository is already a sort of service. More specifically, a repository implementation can be thought of as an infrastructure service.
It is the application service which calls a repository in order to implement some use case. It delegates to domain entities and orchestrates other services that may be required for a given operation. Take a look at Services in DDD for an example of the various services interacting.