Mvc3 custom event hooks - asp.net-mvc-3

I have a Mvc3-Project where I want to register to custom event hooks.
So that I can register to an event like "User logon". I do not want to do it in the controller, because there is a business logic behind it in an other project.
So in my Mvc3-Project I want to write some classes that will have the code that has to be executed when a User is loged on. But how do I register these classes (or an instance of them) to the event. Is it a good idea to use reflection an search for all classes inherited from a special base class, or is there an other smarter way?
So again, I do not want to monitor the action that is called, I want that the business logic triggers some classes in my Mvc3-Project.

EDIT
As Chris points out in the comments below, MVC3 is stateless, meaning that with this solution you would have to resubscribe for these events on every request. This is probably not a very good solution for MVC.
Have you considered an global event service?
Rough example:
class Example : IEventReceiver
{
public void Init()
{
EventService.Subscribe("Logon", this);
}
private void OnEvent(string eventName)
{
// Do logon stuff here.
}
}
You would need to create the EventService class, which might be a singleton or service. It might have interface similar to the following:
public interface IEventService
{
void Subscribe(string eventName, IEventReceiver receiver);
void Unsubscribe(string eventName, IEventReceiver receiver);
void DispatchEvent(string eventName);
}
public interface IEventReceiver
{
void OnEvent(string eventName);
}

Related

accessing dbcontext within an Authroization Policy Requirement Handler

in a previous posting from a few years ago - Can Policy Based Authorization be more dynamic?
one of the answers offers up the following code:
Then define the handler.
public class MinimumAgeHandler : AuthorizationHandler<DataDrivenRequirement>
{
protected override void Handle(AuthorizationContext context,
DataDrivenRequirement requirement)
{
// Do anything here, **interact with DB**, User, claims, Roles, etc.
// As long as you set either:
// context.Succeed(requirement);
// context.Fail();
}
}
I am using .NET Core 3 MVC with EntityFrameworkCore. I wish to interact with a database in the Handler. The Handler is not passed a dbcontext like a Controller is. I have tried several ways to do it without any success. Does anyone know how to access a dbcontext from here?
Just so you know, the closest I came was using the following code from another post - How to access dbcontext & session in Custom Policy-Based Authorization
public class CheckAuthorizeHandler : AuthorizationHandler<CheckAuthorizeRequirement>
{
MyContext _context;
public CheckAuthorizeHandler(MyContext context)
{
_context = context;
}
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
MyRequirement requirement)
{
// Do something with _context
// Check if the requirement is fulfilled.
return Task.CompletedTask;
}
}
but got the following error: InvalidOperationException: Cannot consume scoped service 'NASAppsAdmin.Models.NASAppsDbContext' from singleton 'Microsoft.AspNetCore.Authorization.IAuthorizationHandler'.
InvalidOperationException: Cannot consume scoped service 'NASAppsAdmin.Models.NASAppsDbContext' from singleton 'Microsoft.AspNetCore.Authorization.IAuthorizationHandler'. Entity Framework contexts are usually added to the service container using the scoped lifetime, if you'd like to use database context from your handler, plese make sure your handler is not registered as singleton. – Fei Han

How to use events for communication between tiers in an MVC application

I am trying to use events as a form of communication between the tiers in a 3 tier application since events are recommended way to avoid coupling between tiers. However I am not able to figure how to use events when synchronous response is needed in the result like in case of a MVC web application. Consider below example
//1. Repository for Employee (Database Tier)
interface IEmployeeRepository
{
//event to signal add complete in repository
public event EventHandler event_EmployeeAdded_To_Repository;
void AddEmployee(Employee emp);
}
public class EmployeeRepository: IEmployeeRepository
{
//implementation of event
public event EventHandler event_EmployeeAdded_To_Repository;
public void AddEmployee(Employee emp)
{
//Save to database
//Fire event to signal add complete in repository
event_EmployeeAdded_To_Repository(null,e);
}
}
//2. Business Tier for Employee
interface IEmployee
{
//event to signal add complete in business tier
public event EventHandler event_EmployeeAdded_To_Entity;
public void AddEmployee();
}
public class Employee : IEmployee
{
public event EventHandler event_EmployeeAdded_To_Entity;
IEmployeeRepository _empRepository;
//constructor injection
public Employee(IEmployeeRepository empRepository)
{
this._empRepository = empRepository;
//Add event handler for the repository event
this._empRepository.event_EmployeeAdded_To_Repository += OnEmployeeAddedToRepository;
}
public void AddEmployee()
{
//Call repository method for adding to database
_empRepository.AddEmployee(this);
}
//Event handler for the repository event
public void OnEmployeeAddedToRepository(Object sender, EventArgs e)
{
//Fire event to signal add complete in business tier
event_EmployeeAdded_To_Entity(null, e);
}
}
//3. Presentation Tier
public class EmployeeController : Controller
{
IEmployee _emp;
//constructor injection
public EmployeeController(IEmployee emp)
{
this._emp = emp;
//Add event handler for business tier event
this._emp.event_EmployeeAdded_To_Entity += OnEmployeeAddedToEntity;
}
//This is an Ajax method call
public ActionResult Add()
{
//Call add method of business tier
_emp.AddEmployee();
//What do I do here ?
}
//Event handler for the business tier event
public void OnEmployeeAddedToEntity(Object sender, EventArgs e)
{
//What do I do here ?
}
}
In above example, I have defined event "event_EmployeeAdded_To_Repository" in the Repository (Database tier) to notify addition completion in repository. In the business tier I have defined event handler "OnEmployeeAddedToRepository" that handles this event. The "OnEmployeeAddedToRepository" event handler in turn fires the event "event_EmployeeAdded_To_Entity". Finally in the presentation tier I have defined event handler "OnEmployeeAddedToEntity" for handling the business tier event.
But in the controller I have an action "Add" that needs to return a response synchronously (after "AddEmployee" has completed) to notify user (or maybe call another ajax action). Firing an event will simply change the flow of control from the action to the event handler.
So then how will you use events in this scenario ?
So then how will you use events in this scenario?
The short answer is: you won't :)
You are in a situation where you have a hammer and you are looking for a nail. Rather determine why you need to do this.
Typically you will have very little use within a domain of knowing when something happened in the domain itself. You could take a look at domain events. But once again, a particular domain will probably be more interested in something happening in another domain.
If you do find yourself needing to know on the web-server that an employee was added then I would go with domain events anyway. A domain event would typically be used to publish the event on a service bus that other systems subscribe to. For instance, once you add an employee in the HR system the access control system would like to know so that it can start issuing a card. In this case the access control system would have it's endpoint subscribe to the Company.HR.Messages.EmployeeAddedEvent message.

Implement Idisposable on mvc3 controller

I have a controller that instantiates a database context for EF. (As I'm sure most that aren't implementing the repository pattern do.)
When I ran code analysis on my project it recommended implementing IDisposable so I wrote the following code.
#region Implementation of IDisposable
public void Dispose()
{
Console.WriteLine("Dispose");
Dispose(true);
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
protected override void Dispose(bool disposing)
{
Console.WriteLine("Dispose(disposing)");
if (disposing)
{
// free managed resources
if (_dataService != null)
{
((IDisposable)_dataService).Dispose();
_dataService = null;
}
// free managed resources
if (_db != null)
{
((IDisposable)_db).Dispose();
_db = null;
}
}
base.Dispose(disposing);
}
#endregion
I've also tried doing.
protected new virtual void Dispose(bool disposing)
But my console.writeline statements never execute. What am I doing wrong? Why isn't Dispose() being called on my controller?
you don't do anything wrong. You get the recommentation because you hold some fields in your class (cotnroller) that implements IDisposable. The framework will call the "overload"-version so just move all your code in there.
Details on MSDN
BTW you won't see the console-writeline - use System.Diagnostic.Debug.WriteLine instead
Personally I think the best thing to do in this situation is to split out the database context away from the controller and move it to a service layer. You can them make that class implement IDisposable and pass the reference to the service layer class to the controller to use it
In doing this you will create a controller that is not dependant on the database. The term skinny controllers, fat models applies here. the service layer will act as a model in this instance. You can also unit test the service layer and controller (if you want) in isolation from each other

GWT Custom Events

Hey I have a problem getting my head around how custom GWT event Handlers work. I have read quite a bit about the topic and it still is some what foggy. I have read threads here on Stackoverflow like this one GWT Custom Event Handler. Could someone explain it in an applied mannar such as the following.
I have 2 classes a block and a man class. When the man collides with the block the man fires an event ( onCollision() ) and then the block class listens for that event.
Thanks
Events in general:
Events are always sent to inform about something (e.g. a change of state). Let's take your example with a man and a wall. Here we can imagine that there is a game where a user can walk as a man in a labyrinth. Every time a user hits the wall it should be informed about the collision so that it can react to it (e.g. a wall can render itself as a destroyed wall). This can be achieved by sending a collision event every time the collision with a wall is detected. This event is sent by a man and every object in the system interested in the event receives it and can react to it accordingly. Objects which want to receive events must register themselves as interested with event.
This is how events work in general in every system or framework (not only in GWT). In order to send and receive events in such systems you have to define:
What is sent (what do events look like)
Who receives events (event receivers)
Who sends events (event senders)
Then you can:
Register event receivers which want to receive events
Send events
Events in GWT:
Here I will show an example of using custom events in GWT. I will use an example of a system which is responsible for checking a mailbox and inform a user if there are new mails. Let's assume that in the system there are at least 2 components:
message checker responsible for checking the mailbox and
message displayer responsible for displaying new mails
Message checker sends events when a new mail is received and message displayer receives these events.
Step 1: Define events
Information about a new mail will be sent as an instance of MessageReceivedEvent class. The class contains a new mail (for the simplicity let's assume it is just a String).
Full source code of this class is presented below (the comment for it is below the source code).
public class MessageReceivedEvent extends GwtEvent<MessageReceivedEventHandler> {
public static Type<MessageReceivedEventHandler> TYPE = new Type<MessageReceivedEventHandler>();
private final String message;
public MessageReceivedEvent(String message) {
this.message = message;
}
#Override
public Type<MessageReceivedEventHandler> getAssociatedType() {
return TYPE;
}
#Override
protected void dispatch(MessageReceivedEventHandler handler) {
handler.onMessageReceived(this);
}
public String getMessage() {
return message;
}
}
MessageReceivedEventHandler is an interface that represents event receivers. Don't bother with it at the moment, this will be discussed later.
Every class representing a GWT event has to extend GwtEvent class. This class contains two abstract methods which must be implemented: getAssociatedType and dispatch. However in every event class they are usually implemented in a very similar way.
The class stores information about a received message (see constructor). Every event receiver can get it using getMessage method.
Step 2: Define event receivers
Each event type in GWT is associated to an interface representing receivers of this event type. In GWT receivers are called handlers. In the example an event receiver interface for MessageReceivedEvent will be named MessageReceivedEventHandler. The source code is below:
public interface MessageReceivedEventHandler extends EventHandler {
void onMessageReceived(MessageReceivedEvent event);
}
Each handler has to extend EventHandler interface. It should also define a method which will be invoked when an event occurs (it should take at least one parameter - an event). Here the method is named onMessageReceived. Each receiver can react on an event by implementing this method.
The only event receiver in the example is MessageDisplayer component:
public class MessageDisplayer implements MessageReceivedEventHandler {
#Override
public void onMessageReceived(MessageReceivedEvent event) {
String newMessage = event.getMessage();
// display a new message
// ...
}
}
Step 3: Define event senders
In the example the only event sender is a component responsible for checking mails - EventChecker:
public class MessageChecker implements HasHandlers {
private HandlerManager handlerManager;
public MessageChecker() {
handlerManager = new HandlerManager(this);
}
#Override
public void fireEvent(GwtEvent<?> event) {
handlerManager.fireEvent(event);
}
public HandlerRegistration addMessageReceivedEventHandler(
MessageReceivedEventHandler handler) {
return handlerManager.addHandler(MessageReceivedEvent.TYPE, handler);
}
}
Every event sender has to implement HasHandlers interface.
The most important element here is a HandlerManager field. In GWT HandlerManager as the name suggest manages event handlers (event receivers). As it was said at the beginning every event receiver that wants to receive events must register itself as interested. This is what handler managers are for. They make it possible to register event handlers an they can send a particular event to every registered event handler.
When a HanlderManager is created it takes one argument in its constructor. Every event has a source of origin and this parameter will be used as a source for all events send by this handler manager. In the example it is this as the source of events is MessageChecker.
The method fireEvent is defined in HasHandlers interface and is responsible for sending events. As you can see it just uses a handler manager to send (fire) and event.
addMessageReceivedEventHandler is used by event receivers to register themselves as interested in receiving events. Again handler manager is used for this.
Step 4: Bind event receivers with event senders
When everything is defined event receivers must register themselves in event senders. This is usually done during creation of objects:
MessageChecker checker = new MessageChecker();
MessageDisplayer displayer = new MessageDisplayer();
checker.addMessageReceivedEventHandler(displayer);
Now all events sent by checker will be received by displayer.
Step 5: Send events
To send an event, MessageChecker must create an event instance and send it using fireEvent method. This cane be done in newMailReceived method:
public class MessageChecker implements HasHandlers {
// ... not important stuff omitted
public void newMailReceived() {
String mail = ""; // get a new mail from mailbox
MessageReceivedEvent event = new MessageReceivedEvent(mail);
fireEvent(event);
}
}
I hope it is clear and will help :)
Since this question and the answer from Piotr GWT has added support for a slightly different way to create custom events. This event implementation is specific build to be used with the GWT's EventBus in the package com.google.web.bindery.event.shared. An example on how to build a custom event for GWT 2.4:
import com.google.web.bindery.event.shared.Event;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.HandlerRegistration;
/**
* Here is a custom event. For comparison this is also a MessageReceivedEvent.
* This event extends the Event from the web.bindery package.
*/
public class MessageReceivedEvent extends Event<MessageReceivedEvent.Handler> {
/**
* Implemented by methods that handle MessageReceivedEvent events.
*/
public interface Handler {
/**
* Called when an {#link MessageReceivedEvent} event is fired.
* The name of this method is whatever you want it.
*
* #param event an {#link MessageReceivedEvent} instance
*/
void onMessageReceived(MessageReceivedEvent event);
}
private static final Type<MessageReceivedEvent.Handler> TYPE =
new Type<MessageReceivedEvent.Handler>();
/**
* Register a handler for MessageReceivedEvent events on the eventbus.
*
* #param eventBus the {#link EventBus}
* #param handler an {#link MessageReceivedEvent.Handler} instance
* #return an {#link HandlerRegistration} instance
*/
public static HandlerRegistration register(EventBus eventBus,
MessageReceivedEvent.Handler handler) {
return eventBus.addHandler(TYPE, handler);
}
private final String message;
public MessageReceivedEvent(String message) {
this.message = message;
}
#Override
public Type<MessageReceivedEvent.Handler> getAssociatedType() {
return TYPE;
}
public String getMessage() {
return message;
}
#Override
protected void dispatch(Handler handler) {
handler.onMessageReceived(this);
}
}
The event is used as follows:
To register your handler for this event with the eventbus call the static register method on the MessageReceivedEvent class:
MessageReceivedEvent.register(eventbus, new MessageReceivedEvent.Handler() {
public void onMessageReceived(MessageReceivedEvent event) {
//...do something usefull with the message: event.getMessage();
}
});
Now to fire the event on the eventbus call fireEvent with a newly constructed event:
eventBus.fireEvent(new MessageReceivedEvent("my message"));
Another implementation can be found in GWT's own EntityProxyChange event class. That implementation uses a alternative option of the EventBus. It uses the ability to add handlers that are bound to a specific source, via addHandlerToSource and can be triggered via eventBus.fireEventFromSource.
The event implementation given here is also more suitable when working with GWT's Activities.
I created my own widget by extending GWT's Composite class. I wanted to create my own custom event in this class. I wanted the events to be accessible to GWT's WindowBuilder Editor.
I learned a lot of from the answers on this page, but I had to make some changes.
I wanted to start from the Hilbrand Bouwkamp answer, because it was newer. But I ran into a couple of problems. 1) That answer made reference to the event bus. The even bus is a global variable owned by the main program. It's not clear how a widget library could get access to that. 2) I wasn't starting from scratch. I was was extending GWT library code. In order to make that work, I had to start from the GwtEvent class, rather than the Event class.
Piotr's answer is essentially correct, but it was very long. My class (indirectly) extends GWT's Widget class. Widget takes care of many details, such as creating a HandlerManager object. (I looked through the source code, and that's exactly how standard Widgets work, not by using an EventBus.)
I only had to add two things to my widget class to add a custom event handler. Those are shown here:
public class TrackBar extends Composite {
public HandlerRegistration addValueChangedHandler(TrackBarEvent.Handler handler)
{
return addHandler(handler, TrackBarEvent.TYPE);
}
private void fireValueChangedEvent(int value)
{
final TrackBarEvent e = new TrackBarEvent(value);
fireEvent(e);
}
My new event is almost exactly the same as Piotr's event class, shown above. One thing is worth noting. I started with getValue(), based on that example. Later I added getTrackBar() to give a lot more information. If I was starting from scratch I'd focus on the latter, not the former. The complete event class is shown below.
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
public class TrackBarEvent extends GwtEvent< TrackBarEvent.Handler >
{
public interface Handler extends EventHandler {
void onTrackBarValueChanged(TrackBarEvent event);
}
static final Type<TrackBarEvent.Handler> TYPE =
new Type<TrackBarEvent.Handler>();
private final int value;
public TrackBarEvent(int value) {
this.value = value;
}
#Override
public Type<TrackBarEvent.Handler> getAssociatedType() {
return TYPE;
}
public int getValue() {
return value;
}
public TrackBar getTrackBar()
{
return (TrackBar)getSource();
}
#Override
protected void dispatch(Handler handler) {
handler.onTrackBarValueChanged(this);
}
}
If you happen to be using the GWTP framework on top of GWT, refer to this Stack.
GWTP is "A complete model-view-presenter framework to simplify your next GWT project."

Are "passive" objects considered a good design practice?

I find myself very often creating an object that has no public methods and is self-contained. It typically handles events of arguments passed to its constructor in its private methods and does not raise any events or expose any public methods.
I am calling this type of objects "passive" objects - objects that do not have any public methods defined. All interaction occurs inside them in private methods and events of arguments passed in constructor.
Typically it is some utility class, like one that assures that two forms will be sticked together:
public class StickyForm : IDisposable
{
private readonly Form form;
private readonly Form parentForm;
public StickyForm(Form form, Form parentForm)
{
this.form = form;
this.form.StartPosition = FormStartPosition.Manual;
this.parentForm = parentForm;
this.parentForm.LocationChanged += new EventHandler(parent_LocationChanged);
this.parentForm.SizeChanged += new EventHandler(parent_SizeChanged);
SetLocation();
}
void parent_SizeChanged(object sender, EventArgs e)
{
SetLocation();
}
void parent_LocationChanged(object sender, EventArgs e)
{
SetLocation();
}
private void SetLocation()
{
//compute location of form based on parent form
}
public void Dispose()
{
this.parentForm.SizeChanged -= parent_SizeChanged;
this.parentForm.LocationChanged -= parent_LocationChanged;
}
}
But sometimes it is also some kind of controller, providing interaction between two views:
public class BrowseController
{
private IBrowserView view;
private IFolderBrowser folderBrowser;
public BrowseController(IFolderBrowser folderBrowser, IBrowserView view)
{
this.view = view;
this.folderBrowser = folderBrowser;
this.folderBrowser.NodeOpened += folderBrowser_NodeOpened;
}
private void folderBrowser_NodeOpened(object sender, Core.Util.TEventArgs<IPictureList> e)
{
this.Browse(e.Value);
}
public void Browse(IPictureList content)
{
//stripped some code
AddItemsToView(content);
}
private void AddItemsToView(IPictureList browser)
{
//call methods on view
}
}
Are such "passive" objects considered a good design practice?
Is there a better name for this kind of class?
Seems like fine design to me. I'm not sure about the name passive though. Those classes do seem pretty active. They react to events and do stuff. I would think a class is more passive if you have to call methods on it to get it to do stuff, but normally it wouldn't do anything unless poked.
How about the name "controller". "controller" is the more usual name for a class used in a UI that causes interaction between a view and data, and they quite often don't need to have public methods.
I'm sure there's other ideas for names.
I don't see anything wrong with that. If it results in clean, readable code, go for it!
I wouldn't call the objects that react to notifications and update their state completely passive.
One other thought, if the objects simply adjust their state to reflect changes in the outside world without providing much of their own, you may slice their "functionality" and put it into other more active "components". There may be not enough reason for these objects to exist.
If this organization however makes you code structure better, clearer and more maintainable, then use it and don't worry about it.
I think that there's one important criteria to meet with this design: can you test it? The designs you have seem to be testable, but you may have to be careful as I can see this leading to some rather untestable code.
In regards to the name, I think this may be an example of the Mediator pattern.
Conceptually this appears to be an implementation of strategy pattern. Although in this particular case the reasoning is different from strategy pattern', it still yields very readable and nicely granulated code. Go for it.
UPDATE: to make a little clearer what I mean consider two (or more) classes derived from StickyForm
public class VeryStickyForm : StickyForm
{
//some implementation here
//but interface is completely inherited from StickyForm
}
public class SomewhatStickyForm : StickyForm
{
//some implementation here
//but interface is completely inherited from StickyForm
}
And you decide which one to use dynamically depending on run-time state... you implement a strategy.
As I said your solution is conceptually similar to strategy: you select some behavioral aspect of your application that can be well abstracted into policy and move the implementation of the policy into separate class, that does not know about the rest of the application, and your application does not know much about guts of the policy. Even though you do not use it polymorphically, resemblance to strategy is clear.

Resources