Why do we need a interface to define every service in aem? - service

I have been working with for a while but somehow never thought about this. Every aem project that I have worked on, has one similarity in their code structure. There is an interface for every service written.
My question is why do we need a interface for every service?
Can #reference or #inject not use the services without an interface?

Using interfaces is a good practice to decouple the user of a service from the implementation. In many cases you even want to have an API bundle so the user of the service does not need a maven dependency to the implementing bundle.
On the other hand you are not required to use interfaces. Especially when I wire components inside a bundle interfaces are often an unnecessary layer. In this case simply export the service directly with the class.
See here for an example:
#Component(service = DistributionMetricsService.class)
public class DistributionMetricsService {
...
}
and here for the client code:
#Reference
private DistributionMetricsService distributionMetricsService;
So the main difference is that you have to specify the service property if you want to export a component with its implementation class.

Related

Dependency Injection, EF Core + web api 2 architecture

My layout
project.web (.net core 2.1 web api)
Some binding models (for post/put requests) and resource models for GET requests
Controllers.
I only call interfaces from (x.api) which are resolved to x.core services.
No validation or anything. This happens inside the core layer
I've setup a few things like automapper and swagger, that are not relevant for my question.
project.api (class lib)
only contains interfaces for .core and .store projects (services, repositories and domain models)
project.core (class lib)
two kinds of services
1) Services which call the repository services (interfaces). But validate the data before calling the repo service.
2) Services that will have to execute long term stuff (IE: scanning folders, handling file information, ...). I actually created HostedServices for these as a folder could easily contain thousands of files.
project.store (class lib)
Wrapper services for my storage (Only contains helper methods so I don't have to write the same queries a hundred times.)
Problem / question
At this time I have registered all of my services and repositories as singletons in public void ConfigureServices(IServiceCollection services)
because I was using a different storage (nosql, litedb) before refactoring code to EF (sqllite)
Now the problem is that I want to register my DbContext as scoped (by default)
But my repositories (singleton) depend on dbcontext. Which means I will have to make these scoped as well. I'm ok with this, as these are only wrapper services, so I don't have to write the same queries all the time.
But some other services, that will need access to my data are singletons, and I cannot register these as scoped. Contains some data that needs to be the same for every request, and some collections and long running jobs.
I can think of two solutions
The first solution is to make a dependency to IServiceScopeFactory in my repository and use something like using (var scope = ServiceScopeFactory.CreateScope()) { scope.ServiceProvider.GetService(typeof(MyDbContext))... }
this way I can remove the dependency from my repository wrapper, but this doesn't sound clean to me.
The other solution is to register all of my services that only handle database stuff as scoped. (IE customerSservice in core only does validations and calls customerRepository) I remove dependencies from my remaining singleton services.
In those singletons, instead of depending on the customersService, I could use a rest call with restsharp or something similar
Just like how I would consume them from my windows client applications and web client apps.
I don't actually like either. But perheps someone can give me some advice or thoughts?
Well, the two options you laid out are in fact your only two options. The first is the service locator antipattern, which as the name implies, is something you should avoid. However, when you are dealing with singleton-scoped objects needing access to objects in other scopes, there is no other way.
The only other option is to reduce the scope of your services from singletons, such that you can then inject the context directly. Not everything necessarily needs to be a singleton. Generally, if you need to utilize something like DbContext, there's a strong argument to be made that your object should not be singleton-scope in the first place. If you need it to be singleton-scoped, that's most likely an indication that the class is either doing too much or is otherwise brittle.

Build new Object Instances in Zend Service Manager Component

I would like to know in best practice questions and think of easily testable classes, when I need multiple different instances of the same (fabricated) object within a specific class, which approach is recommended?
Before I used the Service Manager build method, but it is no longer recommended to inject Service Manager directly into a class, right?

How do I show REST API and Database Connection in UML Class Diagram?

I am trying to Create Class Diagram for my Web Application but i dont know how to Represent Database Connection and REST API in Class diagrams.
P.S. I am Creating Class Diagram by following model view controller pattern.
A class is a class
In your class diagrams, you model classes of your system. And all the classes look alike:
a database connection would be a class like another, that will keep some properties about the database context and offer methods for connecting to and disconnecting from a given database.
a REST API class would be a class (or a set of classes) like any other. If you're the API consumer you would certainly have no properties in these classes (because REST is stateless and properties create a state). You could for example have a method for every service you could invoke.
Conceptually speaking theses classes in your system are proxies for something which is out of your system, and which would invoke the APIs provided by the database and the webservice.
But perhaps you want to model something else ?
If your system offers an API, and you want to show how the API offered to the external world relates to your internal classes, you could be interested in using a composite structure diagram.
If you want to show the different components if your system, especially how these are wired together using an API, you could be interested in the component diagram.
If your question is not so much about the structure of the classes and the deeper internals of your system, but more about showing that some part are on remote servers or in containers, you could even think of deployment diagrams. But these are more about the concrete layout of the operating infrastructure, and to link it to the classes, you'd need the component diagrams first.

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 :-)

Correct way of using/testing event service in Eclipse E4 RCP

Let me ask two coupled questions that might boil down to one about good application design ;-)
What is the best practice for using event based communication in an e4 RCP application?
How can I write simple unit tests (using JUnit) for classes that send/receive events using dependency injection and IEventBroker ?
Let’s be more concrete: say I am developing an Eclipse e4 RCP application consisting of several plugins that need to communicate. For communication I want to use the event service provided by org.eclipse.e4.core.services.events.IEventBroker so my plugins stay loosely coupled. I use dependency injection to inject the event broker to a class that dispatches events:
#Inject static IEventBroker broker;
private void sendEvent() {
broker.post(MyEventConstants.SOME_EVENT, payload)
}
On the receiver side, I have a method like:
#Inject
#Optional
private void receiveEvent(#UIEventTopic(MyEventConstants.SOME_EVENT) Object payload)
Now the questions:
In order for IEventBroker to be successfully injected, my class needs access to the current IEclipseContext. Most of my classes using the event service are not referenced by the e4 application model, so I have to manually inject the context on instantiation using e.g. ContextInjectionFactory.inject(myEventSendingObject, context);
This approach works but I find myself passing around a lot of context to wherever I use the event service. Is this really the correct approach to event based communication across an E4 application?
how can I easily write JUnit tests for a class that uses the event service (either as a sender or receiver)? Obviously, none of the above annotations work in isolation since there is no context available. I understand everyone’s convinced that dependency injection simplifies testability. But does this also apply to injecting services like the IEventBroker?
This article describes creation of your own IEclipseContext to include the process of DI in tests. Not sure if this could resolve my 2nd issue but I also hesitate running all my tests as JUnit Plug-in tests as it appears impractible to fire up the PDE for each unit test. Maybe I just misunderstand the approach.
This article speaks about “simply mocking IEventBroker”. Yes, that would be great! Unfortunately, I couldn’t find any information on how this can be achieved.
All this makes me wonder whether I am still on the right track or if this is already a case of bad design? And if so, how would you go about redesigning? Move all event related actions to dedicated event sender/receiver classes or a dedicated plugin?
Actually, running a JUnit plug-in test is not that expensive. You can configure the launch configuration to run in headless mode so the only thing loaded is a lightweight PDE without workbench. The same happens when you run a headless build with for example Tycho. Surefire launches your test-bundle as headless plug-in test by default.
The advantage over isolated unit tests is that you can access your plug-in's resources and, most importantly, use dependency injection. If you want to mock an injected object you have to run a plug-in test so you can use InjectorFactory.
This is how you would go about mocking the event service: IEventBroker is an interface, so the only thing you need to do is writing a mock implementation for it
public class IEventBrokerMock implements IEventBroker {
#Override
// Implemented Methods
}
In your test method you would have something like
InjectorFactory.getDefault().addBinding(IEventBroker.class).implementedBy(IEventBrokerMock.class);
ClassUnderTest myObject = InjectorFactory.getDefault().make(ClassUnderTest.class, null);
If you want to work with a context the test method would instead contain
IEclipseContext context = EclipseContextFactory.create();
context.set(IEventBroker.class, new IEventBrokerMock());
ClassUnderTest myObject = ContextInjectionFactory.make(ClassUnderTest.class, context);
If you run this as JUnit plug-in test your object will have the mocked event service injected.
for testing, instead of DI, i use "eventBroker=new org.eclipse.e4.ui.services.internal.events.EventBroker();" to get a eventbroker object to use, it works ok