I'm conducting a test using JOlivers CommonDomain and EventStore with NServiceBus. I need to raise an event in my Aggregate like this:
RaiseEvent(bus.CreateInstance<IPhoneNumberChanged>(m => { m.Number = number; }));
And then later i have this handler:
private void Apply(IPhoneNumberChanged phoneNumberChangedEvent)
{
this.Number = phoneNumberChangedEvent.Number;
}
Unfortunately this doesn't work. I get an exception: "CommonDomain.Core.HandlerForDomainEventNotFoundException: Aggregate of type 'Phone' raised an event of type 'IPhoneNumberChanged' but not handler could be found to handle the message.".
The problem here is the object created from "bus.CreateInstance" since it works with pure concrete classes. But I need my events as interfaces. Can this be solved?
EDIT: Just a note - I don't have to use "bus.CreateInstance" to create the object, it's just the easiest (only) way I currently have to raise the 'IPhoneNumberChanged'. Any other way would also be great - just as long as I have an interface as argument in the handler.
In your constructor for your Phone aggregate, simply add the following:
this.Register<IPhoneNumberChanged>(this.Apply);
That will take care of the exception. The default internal routing mechanism inside of the CommonDomain is a registration-based router than understands how to get an event to the appropriate Handle method--all without using reflection. Another router has been written and is already part of the CommonDomain project which uses reflection and is more convention based.
One quick thought regarding your event name. Rather than saying that the phone number changed, you may want the event to indicate why the phone number changed. From a domain perspective, the why of something is always more interesting and important that the what. The fact that a phone number changed usually isn't interesting. The fact that it changed because the person moved or cancelled their account or whatever--that's interesting and very likely important as well.
Related
I would like to know if there is an elegant way to add scoped properties to Application Insights, something similar to Serilog:
var yearEnricher = new PropertyEnricher("Year", year);
using (LogContext.PushProperties(yearEnricher))
{
// ...
}
In the previous example every log created within the using block will have the property Year stamped on it.
I figured out how to do this when I want the property to be present within the whole request pipeline:
var requestTelemetry = context.Features.Get<RequestTelemetry>();
requestTelemetry?.Properties.Add(propertyName, propertyValue.ToString());
Sometimes I want to create a logging scope in code that is not related to the web context so it doesn't make sense to rely on the IHttpContextAccessor. I acknowledge I could leverage OperationTelemetry and TelemetryClient.StartOperation to achieve my goal but it is cumbersome as I've to implement a few properties in which I've no interest (such as Name, Success, Duration...).
Is there a better way than relying on OperationTelemetry?
If you don't want to use OperationTelemetry, you might want to look into implementing your own ITelemetryInitializer (see documentation here).
It should be fairly easy to implement a stack-like global structure to hold the properties you want to push, and pop the stack on your Dispose method.
Note that you'll probably need to utilize CallContext in order for your stacks to be thread safe.
I need to discard a message if a specific header is present.
I tried to implement a IMutateTransportMessages and call DoNotContinueDispatchingCurrentMessageToHandlers() method inside MutateIncoming but the message is dispatched to handlers anyway.
I can discard the message using an handler but I don't like it because I need also to specify the handlers' order.
Any solution?
Thanks,
Federico
I don't think this will be possible from a message mutator. After all, this isn't really the kind of activity a message mutator should be doing - it has nothing to do with changing the structure of the message.
I agree with you that it sounds messy to do this in a handler, because you're right - then you are very dependent upon the handler order.
Discarding a message due to the presence (or absence) of a header is an infrastructure concern, and since you are using NServiceBus V5, the best way to customize the infrastructure is by customizing the message handling pipeline.
Here's the relevant documentation that covers creating a behavior and inserting it into the pipeline but here's the short version:
You need to create a behavior that implements IBehavior<IncomingContext>. All of the behaviors together form a behavior chain that progress to the next step by calling next() - an Action present in the implementation) method.
Within the behavior, check for your header. To stop processing the message, just don't call next() and call context.DoNotInvokeAnyMoreHandlers() instead.
Create a class inheriting RegisterStep which, from its constructor, will define where in the pipeline to insert your behavior. You could register it right before the MutateIncomingTransportMessage step.
Create a class implementing INeedInitialization (note that this could be the same as the RegisterStep class) which calls busConfig.Pipeline.Register<TClassThatInheritsRegisterStep>().
Again, that's the short version. Check out the docs for the full story and an example.
Shameless plug: This process is also described in detail in Learning NServiceBus - Second Edition in Chapter 7, with an example.
In my current project, there are lots of networking code, and it use the event handler to handle the input message. Is this mechanism different with the call back function ?
Typically not much. The handler is usually used in the context of a UI application where the UI control will call the handler to handle a UI event. The callback function is traditionally used from the C days (Function pointers) and also in the C++ (Functors) world.
As a general concept I would say that the call back functions are primarily used for Asynchronous execution. Where for example, client side function must look something up on the server and it may take a while. So instead of blocking it says :"Call back at this number (myCallBackFunction) when you are done looking up stuff on the server".
Now event handlers are just that: they handle some predefined events. Usually they wait for users to do something like click a button and then they spring into action. They typically but not necessarily expect some sort of input.
Hope this helps.
I have a problem with the dnn module communication. I have a module that implements the module communication interface both listener and sender. in this module, I have a placeholder where I load a new ascx control. the problem is when I want to Communicate from this new dynamically loaded control. In this control i also implemented module communication interfaces( listener and sender). but when I call sender method, in this dynamic loaded control to update an other module (on same page)nothing happens. But then i call a " sender " from the dynamic loaded controls container control( the control where i have the placeholder) it works updating the other module on the same page. It seams that module comunications do not work in dynamic loaded ascx controls at all.
Is there anyone who have any idea , to solve this
/theonealf
I would guess that it's a timing issue. Try loading your dynamic control in the Init event, and see if it will catch the communication being sent.
Agree with #bdukes, Also there are additional things that I would recommend to check:
Check if there is any exception while nothing happens
Does your control inherits from PortalModuleBase? This will be required if you want to use moduleId, UserInfo, PortalId or any other dnn specific objects.
There can be other checks but it depends on your answer by trying above and #bdukes suggestion.
Honestly, I have had limited success with the communications interface. If you can get to work for your needs, then excellent. In case you find you need another solution, here's what I've done:
If I understand the question correctly, you're concerned with the specific use-case where one module needs to communicate with another module during the loading of a page. If that is so, you most likely have one module which is the one that needs to communicate, and one or more modules which need to pick up that communication.
I've used Context.Items in combination with the ASP.NET life cycle to solve this problem. The Items collection is just a bag that anything can be stuffed into or pulled out of. The module that needs to communicate can put things into that item bag during Page_Load:
var item = "My Thing";
Context.Items.Add("MyThingKey", item);
The modules which need to consume that thing can pull things out of that bag during PreRender.
var item = Context.Items["MyThingKey"].ToString();
The key is doing this during PreRender. This way, you are assured that the consuming of the communication happens after the production of the communication.
Good luck!
We are working on a portal environment. On one of our page we have two portlets. When some action happens on one portlet, we have to minimize the other portlet and viceversa.
So we feel that this is a suitable situation where we can use Dojo's publish/subscribe model. But I'm a bit confused if I need to use different topics [One when some action happens on Portlet A, and the second topic when some action occurs on PortletB] or one topic [something like minimize]. Can someone please guide me.
This is really up to you, and depends on your needs.
Topics are free-form texts, so you can arrange it in any text format you like.
My own experiences have been to treat a topic as an "event". Therefore, one topic, one event.
My experience has also been that it is tremendous beneficial to implement "commands" in the same system as events -- so you have a universal command/event system.
Events (therefore topics) do not have to correspond to your portlets. For instance, one portlet can have multiple events (if they make sense), or one event can be shared by multiple portlets (for shared functionalities or for cross-portlet communcations).
Parameters and data can be passed with the event (i.e. topic) as arguments.
Now, a good trick I've learnt is to have "sub-topics" -- i.e. topics that are prefixed with an parent topic, when things want to subscribe to a particular instance of event.
Example: Assume we have an event called "/portlets/showhide" which is published by any portlet when it is shown or hidden, together with the id of the portlet and a boolean variable indicating whether it is shown or hidden.
Now, assume that a portlet will also publish topics called "/portlets/showhide/{id}" (with true/false argument) and "/portlets/showhide/{id}/show" (no arguments) when shown, together with the generic "/portlets/showhide" topic (event).
Now assume some handler object is really only interested when the "xyz" portlet is hidden. It doesn't have to subscribe to "/portlets/showhide" and listen to all those events of other portlets that it is not interested in. It can simply subscribe to "/portlets/showhide/xyz/hide". When number of subscriptions increase in a large system, this kind of optimizations can come in quite handy.
You can use one topic in which pass additional parameters. Something like this:
// PortletA
dojo.publish("onPortletAction", [{sender: "PortletA"}]);
// PortletB
dojo.publish("onPortletAction", [{sender: "PortletB"}]);
....
dojo.subscribe("onPortletAction", dojo.hitch(window, window.processAction));
window.processAction = function(data) {
if (data.sender == "PortletA"){
//to do something
}
if (data.sender == "PortletB") {
//to do something
}
}