Why do we need to set the recipient explicitly for IMessenger.Subscribe()? - mvvm-light

Here is the singature of the Register method:
IMessanger.Register<TMsg>(object recipient, Action<TMsg> action);
Why do we need the recipient if action holds the reference in its Target property?
When the given action does not use instance members of the class where it was defined then Target is null.
But this happens quite rarely. I mean that it is not a very common way we use event handlers.
I'd like to understand why there is no additonal Register method signature with no recipient parameter? Am I missing something important?
IMessanger.Register<TMsg>(Action<TMsg> action);

You can actually register a recipient for a specific message from anywhere in your application, not just from the class that is the recipient. For example, consider the following scenario:
public class ClassA : ViewModelBase
{
public ClassA()
{
Messenger.Default.Register<SomeMessage>(this, SomeAction);
Messenger.Default.Register<SomeMessage>(ViewModelLocator.ClassB, SomeAction);
}
private void SomeAction(SomeMessage msg)
{
// do something
}
}
public class ClassB : ViewModelBase
{
public ClassB()
{
}
}
In the case of the second Registor method call, the Target property of the Action will NOT be the same as the recipient parameter. Therefore, to be consistent, it was most likely safer to always require a recipient parameter.
Of course, you are correct that this scenario is probably less common than the scenario where you simply pass this as the recipient. So in that case, if typing this becomes to burdensome for you then you could always define your own Register extension method which simply passes the Target property along to the actual Register method:
public static class MessengerHelper
{
public static void Register<TMessage>(this IMessenger messenger, Action<TMessage> action)
{
messenger.Register<TMessage>(action.Target, action);
}
}
You can then register for messages like this:
public class ClassA : ViewModelBase
{
public ClassA()
{
Messenger.Default.Register<SomeMessage>(SomeAction);
}
private void SomeAction(SomeMessage msg)
{
// do something
}
}

It is done so you can say Messenger.UnregisterRecepient(recepient); which then unsubscribes every action registered to this receiver.

Related

Is there a way to reuse in place validation of Hibernate's implementation of Bean Validation at runtime?

For example, I have got a class:
#Getter
#Setter
class Notification {
private String recipient;
private Channel channel;
enum Channel {
SMS, EMAIL
}
}
I could define my own Validator, for instance:
#Target(TYPE)
#Retention(RUNTIME)
#Constraint(validatedBy = {RecipientValidator.class})
#interface ValidRecipient {
// required arguments of validation annotation
}
class RecipientValidator implements ConstraintValidator<ValidRecipient, Notification> {
#Override
public void initialize(ValidRecipient annotation) {
}
#Override
public boolean isValid(Notification value, ConstraintValidatorContext context) {
boolean result = true;
if (value.getChannel() == SMS) {
return matches(value.getRecipient(), "<phone-number-regexp>");
}
if (value.getChannel() == EMAIL) {
// can I reuse Hibernate's Email Validation there?
return matches(value.getRecipient(), "<email-regexp>");
}
return result;
}
}
Of course I can google regexp of email and copy-paste there but Hibernate's Bean Validation implementation already has the Email Validation (under #Email annotation).
Is there a way to reuse that validation implementation in my custom validator?
There is no official way to reuse a validator in another one.
What you can do though would be to initialize an EmailValidator attribute in initialize() and call its isValid() method in your isValid() method.
Keep in mind that EmailValidator is internal so it might be subject to changes in the future.

any work around to allow for an action result to accept a Abstract class as parameter

I have different configurations all inheriting from a base configuration that are customized in forms. I want all of these to be handled by a single action result.
[HttpPost]
public IActionResult Register(AbstractBaseConfig config)
{
...do some logic...
return View("../Home/Index");
}
However, this is not possible because you cannot base in abstract classes as a parameter to an action result. Is there any work around for this so I don't need a seperate action result for each configuration? (I still want each configuration to be it's own class, I only need access to the base class methods in the action result logic).
Basically you can't, and the reason is that MVC will try to do new AbstractBaseConfig() as part of the Data Binding process (which parses the URL or the Form Post and puts the results in a concrete object). And by definition, doing new AbstractBaseConfig() is impossible for an abstract class.
It also makes sense for other reasons, I will explain why.
You seem to expect that MVC can determine the class from the parameters that are being passed in. That is not how it works, in fact the opposite is true: the Action Method has to specify the exact class, and then the Binder will instantiate that exact class and try to bind its properties.
Suppose you had this:
public abstract class Thing { public int ID { get;set; } }
public class NamedThing : Thing { public string Name { get;set; } }
public class OtherThing : Thing { public string Name { get;set; } }
and suppose it would be allowed to use:
public IActionResult Register(Thing thing)
then what would you expect to be in thing after Data Binding: a Thing object with only the ID set? Or one of the other object types, with Name set, but how would MVC ever be able to know which class you meant?
So for all these reasons, this is not possible.
You could have a base class inherit the abstract class and all your classes inherit from that base class whilst having that base class as your parameter
Take for example
public abstract class ABase
{
public void stuff()
{
var stuff = string.Empty;
stuff = "hello";
}
public virtual void otherstuff()
{
var stuff = string.Empty;
stuff = "hello";
}
}
public class Base : ABase
{
//empty
}
public class Derived : Base
{
public void mystuff()
{
this.stuff();
}
public override void otherstuff()
{
// Custom code
}
}
public ActionResult Register(Base config)
{
}

ASP.NET: Implementing Init and Dispose methods

Can an ASP.NET web application have only one Init and one Dispose method or can I implement these per class for those which I want to associate such methods?
More specifically I have Customer component and a CustomerRecord classes and would like to implement Init and Dispose methods in both of them.
What is the proper way to do this?
Requirement:
I want to have independent Init and Dispose methods for each aforementioned class.
For classes that should be disposable, by exposing a public Dispose method, the IDispsable interface must be implemented for 'disposability' to be effective out of the scope of explicit user disposal. This has been covered many times in many places, including here, for example:
public class Customer : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SupressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
//dispose of managed resources
}
//dispose of unmanaged resources
}
~Customer()
{
Dispose(false);
}
}
Note that the destructor (the method starting with the tilde ~) may not be necessary, but read the details from the answer I linked above for clarity on the situation of what and why - this just answers your question directly.
As for an Init method, are you referring to a constructor?
If so, then look at the destructor in the above example; a constructor (or initialiser) can be defined in the same way minus the tilde and, generally, plus an explicit access modifier (public, private, et cetera), for example:
public class Customer
{
public Customer()
{
}
}
You can create a base class with the Init and Dispose method as you wish and then make the other classes to inherit from it. For example:
public class BaseClass
{
public void Init()
{
//Some code
}
public void Dispose()
{
//Some code
}
}
public class Customer : BaseClass
{
//Some code
}
That might help you.

C# - Override <T> method signature with ClassName?

Is there a way to override an abstract class's method signature which uses <T> with a ClassName so I can pass an object by reference without recasting it?
For example, I have a bunch of Object Managers. I want them all to contain a .Save(Object) method which will perform the appropriate save action based on the object state (Insert, Update, Delete, etc).
I was trying to create a base class which contains these methods:
protected virtual bool Update<T>(ref T _object) where T : ObjectBase
{
throw new NotImplementedException();
}
public virtual bool Save<T>(ref T _object) where T : ObjectBase
{
// Figure out which action to take based on _object's state and execute it
}
And I wanted my inherited classes to define the methods using something like this:
public override bool Update<Consumer>(ref Consumer _object)
{
return _service.UpdateConsumer(ref _object);
}
My problem is that I can't specify that <T> will now be <Consumer>, and by keeping it at <T> I can't pass it by ref
Instead of making the methods themselves generic, you should make the entire base class generic.
For example:
public abstract class ObjectManager<T> where T : ObjectBase {
protected abstract bool Update(T obj);
}
Each concrete ObjectManager should inherit ObjectManager of the type that it manages, like this:
public class ConsumerManager : ObjectManager<Consumer> {
protected override bool Update(Consumer obj) {
...
}
}
Note, by the way, that your parameters should almost definitely not be passed ref.
You only need to ref keyword if you want to change the caller's variable to refer to a different instance.
For more information, see here.

Factory Method Pattern clarification

My understanding of Factory Method Pattern is (Correct me if i am wrong)
Factory Method Pattern
"Factory Method allow the client to delegates the product creation (Instance Creation) to the subclass".
There are two situation in which we can go for creating Factory Method pattern.
(i) When the client is restricted to the product (Instance) creation.
(ii) There are multiple products available.But a decision to be made which product instance
need to be returned.
If you want to create Abstract Method pattern
You need to have abstract product
Concrete Product
Factory Method to return the appropriate product.
Example :
public enum ORMChoice
{
L2SQL,
EFM,
LS,
Sonic
}
//Abstract Product
public interface IProduct
{
void ProductTaken();
}
//Concrete Product
public class LinqtoSql : IProduct
{
public void ProductTaken()
{
Console.WriteLine("OR Mapping Taken:LinqtoSql");
}
}
//concrete product
public class Subsonic : IProduct
{
public void ProductTaken()
{
Console.WriteLine("OR Mapping Taken:Subsonic");
}
}
//concrete product
public class EntityFramework : IProduct
{
public void ProductTaken()
{
Console.WriteLine("OR Mapping Taken:EntityFramework");
}
}
//concrete product
public class LightSpeed : IProduct
{
public void ProductTaken()
{
Console.WriteLine("OR Mapping Taken :LightSpeed");
}
}
public class Creator
{
//Factory Method
public IProduct ReturnORTool(ORMChoice choice)
{
switch (choice)
{
case ORMChoice.EFM:return new EntityFramework();
break;
case ORMChoice.L2SQL:return new LinqtoSql();
break;
case ORMChoice.LS:return new LightSpeed();
break;
case ORMChoice.Sonic:return new Subsonic();
break;
default: return null;
}
}
}
**Client**
Button_Click()
{
Creator c = new Creator();
IProduct p = c.ReturnORTool(ORMChoice.L2SQL);
p.ProductTaken();
}
Is my understanding of Factory Method is correct?
What you have there is actually more of an Abstract Factory Pattern, only that you factory (Creator) is not abstract. The factor method pattern is specifically useful for subclassing:
class A {
public:
A() : m_Member( GetMember() )
{
}
protected:
virtual ISomeInterface * GetMember() { // default impl here }
private:
ISomeInterface * m_Member;
}
Now subclasses of A can override GetMember to make the superclass use a specific implementation of ISomeInterface.
Define an interface for creating an
object, but let subclasses decide
which class to instantiate. Factory
Method lets a class defer
instantiation to subclasses.
more details and example there: http://www.dofactory.com/Patterns/PatternFactory.aspx
Yes, that appears to be a correct way to implement this, although pretty simplistic. In reality, you may want to account for the passing-in of various parameters that may not always be consistent across all types. Dictionaries/Lists/Hashtables/etc. are useful for this, as is serialized items and/or XML and other dynamicish things.

Resources