Suppose a Prism version 8 WPF module has a ViewModel which needs to call on a service.
the service implements IService, but there exists a number of implementations of this service. Each implementation is a file (class library), possibly as a IModule (see below).
The user shall be able to configure which file to use either by configuration or by a folder's content.
Obviously(?) I am thus thinking of Module discovery by creating the right type of ModuleCatalog while "bootstrapping" the application and the service could thus be contained in this module.
If the call is a void call ("fire-and-forget") I guess I could simply use EventAggregator (implementing the service as an observer), however the call returns a value.
What is the best approach solving this?
(I would like to avoid writing my own assembly "discovering/loading" of some kind of a swappable service implementation dll file)
If you can inject IEventAggregator, you can inject IService, can't you?
If no module registered an implementation, you'll get an exception. If more than one module did, the last one wins (with unity as container, at least).
Related
I'm trying to create a service such that once it is created it only allows itself to be held by a single consumer/bundle at any one time. (If this is against the philosophy/specification of OSGi then that obviously provides a quick answer but reference to the OSGi specs. stating this would be appreciated.)
To implement such a requirement I implemented the ServiceFactory interface thinking that whenever there was a requirement for the service the getService(Bundle bundle, ServiceRegistration<S> registration) method would be called and it would be where I could determine if the Bundle was a new consumer or not and act accordingly.
It appears that this is not the case in the scenario I have tested this in.
Using a Apache Karaf and instantiating a consumer of the Service via Blueprint it would seem that the getService method is never called. Instead the consumer's binding method for the service is called directly but injecting a proxy service object.
While I understand that Blueprint uses proxies surely there is still the obligation of the ServiceFactory contract to fulfil even if it's a proxy object consuming the service?
Why do I want to do this?
I am attempting to wrap JavaFX and the Stage class and because JavaFX isn't OSGi friendly I am attempting to co-ordinate access to the Stage object. I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
It depends what you mean by a consumer. ServiceFactory does give you the chance to create a separate instance of a service per bundle that calls getService on your service. It's not clear from your question but I suspect you weren't seeing the getService invoked multiple times because you were fetching the service from the same consumer bundle. In this case, ServiceFactory simply returns the same object repeatedly.
As for your general question about restricting access to a single consumer, no that really goes against the OSGi philosophy. I'm sorry I don't have a spec reference for you but the clue is in the name: it's a service that is available to all.
I'm aware that there are frameworks such as Drombler but a brief look at them made me think that it doesn't suit my use case. They appear too restrictive for my needs e.g. I don't necessarily wish to layout an application in the manner Drombler uses.
Please note that the layout of Drombler FX applications is pluggable so you can provide your own implementation tailored to your needs. This allows you to get the most out of Drombler FX and JavaFX.
While this feature is available for some time, there is now a new tutorial trail explaining it in more detail.
I have a use case, that theoretically seems to me as it would be a solved problem. But i'm not able to find a sure fired implementation.
I've created a RESTful API, using Apache CXF, Spring and Hibernate
This application encompasses a standard Service-Proxy-DAO layered structure
I need to instantiate a custom logger object at my service (or pre-service) layer and initialize a bunch of parameters which will remain constant, for the most part through every call that goes through my application layers and back.
How can i, for every individual service call, initialize this logger object once, and use it across all my layers without having to instantiate it everytime. Either i inject the initialized object in every class i need or something on those lines.
I don't want to use static blocks, or pass the object in method signatures.
Is there anything that i can use as a part of the Spring, CXF or other java framework that allows me to implement this use-case.
EDIT: I would define a transaction as a single call to a web service endpoint, from invocation to response.
ThreadLocal would be an ideal candidate to solve your problem.
UPDATE:
Creating a thread local that is available in all the places where this "shared" reference is required will give all these contexts access to this resource without having to pass the reference around.
see http://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/ - looks like a good explanation of how to use thread local and also deals with your problem space.
My application obtains class names from a properties file. Classes represented by these class names could reside in certain OSGI bundles unknown at advance so in order to instantiate them I firstly have to find which bundle these classes belong to. I'm thinking about getting all installed bundles from BundleContext#getBundles, this means I have to obtain reference to BundleContext in AbstractUIPlugin#start. But I'm not sure if holding reference to BundleContext is the right thing to do since it's should be used only in the start method. So I need advice from OSGI experts here about the alternatives to get list of bundles.
Any help would be greatly appreciated.
Regards,
Setya
This is not really how OSGi is intended. If a bundle has something to add to the 'global' context, you should register a service. So each bundle that has something to share can do that in its own start method.
Some other component (DS, ServiceTracker, Blueprint, something like that) can then listen to these events, and act accordingly.
This is really important, if you start manually searching through all bundles you completely lose the advantages of OSGi.
Like written before you should try to use services to achieve what you want. I guess you have an Interface with one or more implementations that should be installable at runtime. So if you control the bundles that implement the interface then simply let them install their implementation as a service by using an Activator or a blueprint context. You can use service properties to describe your implementation.
The bundles that need the implementation can then lookup the services using a service tracker or a service reference in blueprint.
If that is not possible then you can use the bundle context to obtain the running bundles and instantiate the classes but this is not how OSGi should work. You will run into classloading problems as the bundle that tries to instantiate the classes will not have direct access to them.
Your bundle gets control at start up through the bundle activator, or better, through DS. At that time it can register services with the services registry so others can find/use them.
The route your planning to go (properties that name classes) is evil since you undoubtedly will run in class loading hell. Modularity is about hiding your implementation details, the name of your implementation classes are such details.
Exposing implementation classes in properties files is really bad practice and it looses the advantage of modularity. It does not matter if another class refers to your implementation class or a property file, the problem is that the impl. class is exposed.
Unfortunately this model has become so prevalent in our industry that many developers think it is normal :-(
OSGi allows you share instances typed by interfaces in a way that allows the implementation class to only be known inside the module.
I have seen this line of code in several tutorials for using Unity in asp.net mvc3. I was under the impression that Service Locator is an anti-pattern and not best practice. Is this Service Locator something other than the anti-pattern defined, or is this line of code / this implementation considered bad practice.
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));
Old question, but for the benefit of others:
While I absolutely agree with the mantra "Service Location is an anti-pattern", there are definitely exceptions to that rule.
When you use Dependency Injection (like Unity) then, yes, certainly don't use ServiceLocator and only use constructor injection for all your service classes. (Also don't use "new" for anything other than value objects like DTOs.)
However, there are cases where you simply can't use constructor injection and then the only way to get access to a service is to use a workaround to access your Unity container directly, and in such cases, ServiceLocator is a good standard way to accomplish that. This is the case when the class isn't instantiated by you (or more specifically, it isn't instantiated by Unity) but by the .NET framework for example.
A few simple examples of where ServiceLocator might be useful, is to get access to services registered in your Unity container from:
an implementation of a WCF IEndpointBehavior or IClientMessageInspector
an implementation of a WPF IValueConverter
or you may not necessarily even want to get access to "services" from the class, but you simply want to write code that is unit-testable, but for some reason the class can't be instatiated at all (or not easily) because it would normally be constructed by the .NET Framework, so you extract your custom code into a class that is testable, and resolve it in the non-testable class using the ServiceLocator.
Note that this line is not ideal:
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));
The ServiceLocator.Current property is going to execute the delegate provided every time you access Current, i.e. a new UnityServiceLocator is going to get created every time. Instead, you probably want to do this:
IServiceLocator locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
If you create a framework which is designed to be container agnostic the service locator (although it should be a No-Go in an application) is an additional layer of indirection that allows you to swap out Unity for something different. In addition the use of the service locator does not enforce the use of DI for applications that use that framework.
It is the same anti-patten that people talk about. All that line is doing is setting the service locator provider to be an instance of UnityServiceLocator, i.e. to use the Unity implementation of the ISerivceLocator. Optionally if you would like you can have your own implementation is IServiceLocator and use that instead of UnityServiceLocator.
Using Service Locator is considered a bad practice for various reasons as listed here
I updated Ninject.MVC3 package from 2.2.1.0 to 2.2.2.0. Before I had access to the Kernel object through BootStrapper.Kernel property but in the new version Kernel property is marked as obsolete. I get a warning saying
'Public ReadOnly Property Kernel As Ninject.IKernel' is obsolete: 'Do not use Ninject as Service Locator'.
Is there a different way to access the kernel in the new version?
If you have a class that (for some reason) needs to retrieve objects from the Ninject kernel, you can include the kernel as one of the injected properties/constructor parameters on the class. This pattern is better in the sense that you're explicitly declaring that a particular class is using the kernel, rather than always having it available as the service locator pattern does.
This assumes that Ninject automatically adds an instance binding of the kernel to itself. I know that it used to do this, but if it doesn't you can add the binding manually.
The reason why this has been marked Obsolete and will be changed to internal in future is that people tend to use Ninject as a service locator if it is possible to do so. But Service Locator is an antipattern that should not be used. And as we don't want to provide functionality that helps building badly designed software it will be removed in future.
If this needs a lot of changes in your code this is sign that your code is suffering from this malaise Dependency Injection wise and you really should change it to a better design.
Limit your access to the kernel to a mimimum. There is almost no situation in MVC where you need something other than plain constructor injection. Therefore my first advice is to refactor to constructor injection where possible.
For these very rare cases where you need access to the kernel to create other objects you should inject a factory to the class that needs the new instance and inject the kernel into this factory (if the Constructor has a Kernel parameter, it'll receive the instance doing the injecting).
If you really want to stay with service locator even if almost everyone will tell you not to, you will have to keep a static reference yourself.
In ASP.NET MVC 3, I think DepedencyResolver is a clean way to get a service locator.
You could use the Common Service Locator as a service location hook into Ninject. The Common Service Locator only allows you to retrieve objects though, not inject objects that you already have. Of course you could hack around this restriction, but you could just as easily create a static class that exposes the Ninject kernel and reference that rather than the BootStrapper.