What's the best place to trigger an event in MVC? - oop

Having an MVC system, is it better to trigger events in the controller or in the services that are injected in has dependencies?
Eg.
class MyController
{
$brainStorage->store($yellowBrain);
$EventDispatcher->dispatch(new BrainCreatedEvent($yellowBrain));
...
Or should be the storage service to trigger the event?
I prefer that control classes are the only ones aware of the domain events.
What are pros and cons?

In the case your controller starts doing event handling it will fail single responsability, so the best option in my opinion is to create an abstraction and let the client decide the algorith to inject in application service that will orchestrate your workflow (Use of strategy pattern, IOC, remove code smells, your code will start to be extensible and SOLID) Hope this helps decide, Kind regards!

Related

Can a BackgroundService run indefinitely in ASP .NET Core 3.1?

I am constructing a web service that receives data and updates it periodically. When a user pings the service, it will send specific data back to the user. In order to receive this data, I have a persistent that is created on startup and regularly receives updates, but not at periodic intervals. I have already implemented it, but I would like to add DI and make it into a service. Can this type of problem be solved with a BackgroundService or is this not recommended? Is there anything better I should use? I originally wanted to just register my connection object as a singleton, but since singletons are not initialized on startup, that does not work so well for me.
I thought I would add an answer as so expand on my comment. From what you have described, creating a BackgroundService is likely the best solution for what you want to do.
ASP.NET Core provides an IHostedService interface that can be used to implement a background task or service, in your web app. They also provide a BackgroundService class that implements IHostedService and provides a base class for implementing long running background services. These background services are registered within the CreateWebHostBuilder method in Program.cs.
You can consume services from the dependency injection container but you will have to properly manage their scopes when using them. You can decide how to manage your BackgroundService classes in order to fit your needs. It does take an understanding of how to work with Task objects and executing, queueing, monitoring them etc. So I'd recommend giving the docs a thorough read, so you don't end up impacting performance or resource usage.
I also tend to use Autofac as my DI container rather than the built in Microsoft container, since Autofac provides more features for resolving services and managing scopes. So it's worth considering if you find yourself hitting a wall because of the built in container.
Here's the link to the docs section covering this in much more depth. I believe you can also create standalone service workers now, so that might be worth a look depending on use case.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio
Edit: Here's another link to a guide an example implementation for a microservice background service. It goes a little more in depth on some of the specifics.
https://learn.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice#implementing-ihostedservice-with-a-custom-hosted-service-class-deriving-from-the-backgroundservice-base-class

Zend Framework 3 singletons

I'm creating a new application in Zend Framework 3 and i have a question about a design pattern
Without entering in much details this application will have several Services, as in, will be connecting to external APIs and even in multiple databases, the workflow is also very complex, a single will action can have multiple flows depending on several external information (wich user logged in, configs, etc).
I know about dependency injections and Zend Framework 3 Service Manager, however i am worried about instanciating sereval services when the flow will actually use only a few of them in certain cases, also we will have services depending on other services aswell, for this, i was thinking about using singletons.
Is singleton really a solution here? I was looking a way to user singletons in Zend Framework 3 and haven't figured out a easy way since i can't find a way to user the Service Manager inside a service, as I can't retrive the instance of the Service Manager outside of the Factory system.
What is an easy way to implement singletons in Zend Framework 3?
Why use singletons?
You don't need to worry about too many services in your service manager since they are started only when you get them from the service manager.
Also don't use the service manager inside another class except a factory. In ZF3 it's removed from the controllers for a reason. One of them is testability. If all services are inject with a factory, you can easily write tests. Also if you read your code next year, you can easily see what dependencies are needed inside a class.
If you find there are too many services being injected inside a class which are not always needed you can:
Use the ProxyManager. This lazy loads a service but doesn't start it until a method is called.
Split the service: Move some parts from a service into a new service. e.g. You don't need to place everything in an UserService. You can also have an UserRegisterService, UserEmailService, UserAuthService and UserNotificationsService.
In stead of ZF3, you can also think about zend-expressive. Without getting into too much detail, it is a lightweight middleware framework. You can use middleware to detect what is needed for a request and route to the required action to process the request. Something like this can probably also done in ZF3 but maybe someone else can explain how to do it there.

#RepositoryEventHandler only invoked via HTTP - why?

when I use a #RepositoryEventHandler then its methods are only invoked when the call into the repository comes in via HTTP.
Any reason why? OK, it is called Spring Data REST, but wouldn't it be VERY useful to invoke the handler too, when I call my Repo directly, not via HTTP?
Any way to invoke the handler when called directly (some magic AOP-stuff)?
Thank you
The reason for that is that the different persistence mechanisms covered by the different Spring Data modules already ship with event mechanisms. Depending on the one you use you now get a different mechanism to use.
Unfortunately this can't be unified as e.g. with JPA not all persistence operations need to go through the repository in the first place, as JPA automatically flushes all changes that were made to an attached instance on EntityManager flush. In this case even AOP on the repository instance doesn't help.
So you're basically left with two choices:
The events exposed by Spring Data REST for all repositories (as we basically don't make use of the automatic change tracking in JPA).
The store specific event mechanisms that will make sure that the persistence mechanism exposes events as documented.
I don't know if the solution I put below from other stackoverflow questions would seen as acceptable by #Olivier-drotbohm, but from:
SpringDataRest #RepositoryEventHandler not running when Controller is added
and
#RepositoryEventHandler events stop with #RepositoryRestController
you could inject/autowire the "ApplicationEventPublisher" and fire the BeforeCreateEvent/AfterCreateEvent manually to trigger the RepositoryEventHandler.
This is not a perfect solution, but I hope it is good enough for you (and we tested it: it works).

Spring Data Rest: How do I add logic before validation?

I need to massage some data before a javax validation on save is run. Using "beforeCreate" doesn't work because apparently the validator is called before the "beforeCreate" is. Is there another ApplicationEvent I can use?
Alternatively, can someone answer where I can place business logic in the Spring Data Rest framework? Usually there is a service layer, but they don't seem to exist in this infrastructure.
I think this is not possible. The RepositoryEventHandler and Validator are the hooks that you can work with. If you need more you have to fall back to custom Controllers.
From my point of view the RepositoryEventHandler methods would be the place to plug in up your business logic. You can have a service class as a central place to put your service logic and let the RepositoryEventHandler invoke it.
Why would you actually try to execute business logic before the validation takes place?

linking the EF 4.0 context to the WCF call context

I would like to create an Entity Framework 4.0 context when a call is received and invoke to save changes when it finish, (something like JPA).
I think it is a good idea because I can use the state for all the call, It is short and encapsulate enogh to be threadsafe and long enough for caching calls and the context itself.
Any idea how is the best way for implement this?
Yes, definitely, that's the best way to go.
By default and by best practice recommendation, WCF service calls are "per-call", e.g. each requests gets a brand new, dedicated instance of the service class all to itself - no messy multithreaded/concurrency stuff to deal with - just a nice clean execution environment.
With EF 4, the "disconnected" scenario of sending back entities through WCF was one of the (many) areas that the EF team focused on. See some of these resources for more information:
Building N-Tier apps with EF4
More on disconnected Entity Framework
Attaching modified entities in EF4