What is the purpose and usings of shared services in prism ?
What things can make me think that I have to use shared services instead of EventAggegator?
Looking at EventAggregator from an event subscriber point of view, it's good for getting notified about certain events that occur in the application. This way you're performing an operation passively, i.e. whenever someone else publishes an event. You'd like to use EventAggregator when you need to react to something happening in your application.
On the other hand, with shared services you can actively perform operations and request data. For example, you could have a shared service that exposes a GetData() method, and you could resolve this service and ask for the data actively, any time you need it.
I don't know how other using it but I used it a lot for modularity of my app. For example in Silverlight application for security reasons only OpenFileDialog could return Stream to file. So I just build an IOpenFileService service and plugged it in constructor to any ViewModel that need to open a stream to file. It's also suitable for various Loggers and even Database layer.
Another useful part of services is that they could be build and tested independently from other modules. MEF/Unity will provide all the glue to insert ready objects inside constructor or properties of other objects.
And don't forget that the service class itself could use MEF/Unity magic and insert other services to itself.
And for EventAgregator: You code could became overloaded with various Event definitions very quickly. For example Resize event. On Silverlight app initialization the PRISM Region controls is slow process so the Regions was attached to VisualTree very late and somehow they missing the initial Resize event . I provided the internal Resize event for Region (via EventAgregator) and then another Resize event that each Region control will send to it's children to resize themselves to Region control boundaries. It's 2 Event classes just for Resize...
We have used both, but generally use shared services when the functionality is more than just a simple notification - we also use EventAgregator from within our services in some cases.
For example we have a service for scanning in documents :
public interface IDocumentScannerService
{
}
public class DocumentScannerService : IDocumentScannerService
{
}
This would be a pretty bad design to try and implement this with EventAggregator.
Related
I was looking at saving some data to my Room database and was reevaluating as there are some places in my repositories where I am extending AsyncTask (I'm still using Java) and wanted to check on the state of things to see if it was a good time to swap them out. I saw this reference in the Android developer site on Approaches to background work.
All persistent work: You should use WorkManager for all forms of
persistent work. Immediate impersistent work: You should use Kotlin
coroutines for immediate impersistent work. For Java programming
language users, see Threading on Android for recommended options.
Long-running and deferrable impersistent work: You should not use
long-running and deferrable impersistent work. You should instead
complete such tasks through persistent work using WorkManager.
I started using WorkManager for an API which needed to be called, but for which I could not rely on network connectivity. Because I'm using Room, which is persistent, it seems like I should be using WorkManager.
It defines persistent work as:
Persistent work: Remains scheduled through app restarts and device reboots.
A database insert/update/delete is persistent by this definition. Scheduled throws me off a little, as I want it to be immediate, but according to this chart that would still apply.
Is anybody using WorkManager as the mechanism for CUD operations in their repositories and if so, do they have an example?
It would be great to see how this all works in an update fragment. If a single item is selected and I am viewing it in a fragment, when changes are made I would need to update the database using a Worker class and view the data using a LiveData object, correct?
Inserts and returning the id (or object) would be interesting to see as well.
I have recently created a custom framework that is planned to be re-used for multiple projects. The catch is, this is for a plugin, and knowing that we can't simply embed the framework within the plugin's bundle, due to symbol collisions and what-not, I'm thinking of simply embedding it with the plugin's XPC. On a side-note, this framework will be used to launch custom interfaces, such as a view controller, views, and use some delegates slapped inside it that the plugin will have to take ownership (which I am hoping). Which brings me to my question: is it possible for a different process to take ownership of objects instantiated in the XPC? I am quite new to using frameworks, so I've spent hours trying to jerry-rig stuff together in XCode based on tutorials I've found online, sadly to no avail.
A framework is a bundle of code and resources that can be used, and reused, by multiple applications. It can be embedded within your application, be part of the operating system (the entirety of Cocoa is actually a collection of frameworks), or dynamically located and programmatically loaded at runtime. Once loaded, the framework's code, classes, and resources appear to the application as if they had been compiled directly into the host app. The key is that the code executes directly, in your process's memory space.
XPC is an inter-process communications facility. It allows one process to send and receive messages with a different process. It cannot be used to communicate with itself.
You cannot "take ownership" of an object using XPC. All XPC messages serialize ("archive" in Cocoa-speak) any object and de-serialize that object on the receiving end. The second process now how a replica of the original object; it is not a reference to the original object and is constrained to the boundaries of its process.
If your second process needs to display something, you have (basically) three options:
(1) Make the second process its own application. The second process can be a full-fledged Cocoa app with windows and so forth. You can make it an "accessory" app, so it does not have a menubar or appear in the dock. See LSUIPresentationMode Info.plist property and/or NSApplication.activationPolicy.
(2) The advanced technique is to use an IOSurface. An IOSurface is, essentially, a method by which a second process (your XPC Service) can draw directly into a window of your application. Again, the drawing objects still exist—and are completely isolated in—the second process; but what they draw will appear in your application as if they were local view objects. (This is how Safari works; every browser page is rendered by an isolated background process drawing into a surface.)
(3) Use a poor-man's IOSurface: send your data to the second process, have it render the results into something (pixel array, TIFF, PNG, ...) that can be serialized and drawn by the host app, then use XPC to send that rendered image back to the host app for display.
Daemons and Services Programming Guide
IOSurface
I have an app which needs almost no user interaction, but requires Geofences. Can I run this entirely within a background service?
There will be an Activity when the service is first run. This Activity will start a service and register a BroadcastReceiver for BOOT_COMPLETED, so the service will start at boot. It's unlikely that this Activity will ever be run again.
The service will set an Alarm to go off periodically, which will cause an IntentService to download a list of locations from the network. This IntentService will then set up Geofences around those locations, and create PendingIntents which will fire when the locations are approached. In turn, those PendingIntents will cause another IntentService to take some action.
All this needs to happen in the background, with no user interaction apart from starting the Activity for the first time after installation. Hence, the Activity will not interact with LocationClient or any location services.
I've actually got this set up with proximityAlerts, but wish to move to the new Geofencing API for battery life reasons. However, I have heard that there can be a few problems with using LocationClient from within a service. Specifically, what I've heard (sorry, no references, just hearsay claims):
location client relies on ui availability for error handling
when called from background thread, LocationClient.connect() assumes that it is called from main ui thread (or other thread with event looper), so connection callback is never called, if we call this method from service running in background thread
When I've investigated, I can't see any reason why this would be the case, or why it would stop my doing what I want. I was hoping it would be almost a drop-in replacement for proximityAlerts...
Can anyone shed some light on things here?
The best thing would be to just try it out, right? Your strategy seems sound.
when called from background thread, LocationClient.connect() assumes that it is called from main ui thread (or other thread with event looper), so connection callback is never called, if we call this method from service running in background thread.
I know this to be not true. I have a Service that is started from an Activity, and the connection callback is called.
I dont know about proximity alerts; but I cant seem to find an API to list my GeoFences. I am worried that my database (sqlite) and the actual fences might get out of sync. That is a design flaw in my opinion.
The reason LocationClient needs UI, is that the device may not have Google Play Services installed. Google has deviced a cunning and complex mechanism that allows your app to prompt the user to download it. The whole thing is horrible and awful in my opinion. Its all "what-if what-if" programming.
(They rushed a lot of stuff out the door for google IO 2013. Not all of it are well documented, and some of it seems a bit "rough around the edges").
For a WP7 app I have managed to get a PeriodTask running as per some examples on msdn (sends out a toast message). Now looking to extend to do what I want.
The task is running in the background and I have no need for it to communicate with the foreground app if that is running. I am just a little unsure of what I am allowed to do within this background task, and what code I can access from it.
I would like to be able to access the database that I am using (Sterling) and then update a live tile. Presumably, since its running independently then I will need to open the database - do what I need to do re the tile and then close the database within this background process. This should be okay? And from within my ScheduledAgent class OnInvoke method I can call code that is defined on a class in my foreground project as long as I include a reference to that project in my ScheduledTask project. There are no issues with that code running inside my Background Periodic Task application?
thanks.
In a BackgroundAgent you can do anything apart from use the APIs in the unsupported list: http://msdn.microsoft.com/en-us/library/hh202962(v=vs.92).aspx
The "Marketplace Test Kit" will detect use of any unsupported APIs.
In my solution I added a small Data Model project where I created a class to represent the data/model.
From the main app I store that instantiated object to the isolated storage. In the scheduletaskproject you can then just retrieve that stored instance from isolated storage if you also reference the small Model project.
If I'm not mistaken there is also a 5mb memory limit. So using a DB inside the scheduletaskproject could be a problem ( reference: http://csainty.blogspot.com/2011/08/wp75-mangobackground-agents.html )
I have created apps in the past that would have web pages that would call the persistence layer to get some query results or to insert, delete, etc against a db. However, nothing was left running in the background except for the persistence layer. Now I need to develop an app that has an process that is always running in the background, which is waiting for messages to come thru a zeromq messaging system (cannot change this at this point). I am a little lost as to how to setup the object so that it can always be running and yet I can control or query the results from the object.
Is there any tutorial/examples that covers this configuration?
Thanks,
You could use some kind of timer, to start a method every second to look at a specific ressource and process the input taken from that.
If you use Spring than you could have a look at the #Scheduled annotation.
If your input is some kind of java method invokation, than have a look at the java.util.concurrent Package, and concurrent programming at all. -- But be aware of the fact, that there are some restictions one creating own Threads in an EJB environment.