This commit is contained in:
Lbugnion 2017-10-08 16:31:54 +02:00
Родитель b1a6b1df29
Коммит f46a9fb15c
8 изменённых файлов: 352 добавлений и 108 удалений

Просмотреть файл

@ -10,7 +10,6 @@
// <license>
// See license.txt in this project or http://www.galasoft.ch/license_MIT.txt
// </license>
// <LastBaseLevel>BL0011</LastBaseLevel>
// ****************************************************************************
// <credits>This class was developed by Josh Smith (http://joshsmithonwpf.wordpress.com) and
// slightly modified with his permission.</credits>
@ -43,8 +42,8 @@ namespace GalaSoft.MvvmLight.Command
/// This will enable (or restore) the CommandManager class which handles
/// automatic enabling/disabling of controls based on the CanExecute delegate.</remarks>
////[ClassInfo(typeof(RelayCommand),
//// VersionString = "5.3.14",
//// DateString = "201604212130",
//// VersionString = "5.4.15",
//// DateString = "201612041700",
//// Description = "A command whose sole purpose is to relay its functionality to other objects by invoking delegates.",
//// UrlContacts = "http://www.galasoft.ch/contact_en.html",
//// Email = "laurent@galasoft.ch")]
@ -58,34 +57,42 @@ namespace GalaSoft.MvvmLight.Command
/// Initializes a new instance of the RelayCommand class that
/// can always execute.
/// </summary>
/// <param name="execute">The execution logic. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
/// <param name="execute">The execution logic. IMPORTANT: If the action causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is causing a closure. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
/// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
public RelayCommand(Action execute)
: this(execute, null)
public RelayCommand(Action execute, bool keepTargetAlive = false)
: this(execute, null, keepTargetAlive)
{
}
/// <summary>
/// Initializes a new instance of the RelayCommand class.
/// </summary>
/// <param name="execute">The execution logic. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
/// <param name="canExecute">The execution status logic.</param>
/// <exception cref="ArgumentNullException">If the execute argument is null. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </exception>
public RelayCommand(Action execute, Func<bool> canExecute)
/// <param name="execute">The execution logic. IMPORTANT: If the action causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="canExecute">The execution status logic. IMPORTANT: If the func causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is causing a closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
/// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
public RelayCommand(Action execute, Func<bool> canExecute, bool keepTargetAlive = false)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
_execute = new WeakAction(execute);
_execute = new WeakAction(execute, keepTargetAlive);
if (canExecute != null)
{
_canExecute = new WeakFunc<bool>(canExecute);
_canExecute = new WeakFunc<bool>(canExecute, keepTargetAlive);
}
}

Просмотреть файл

@ -55,34 +55,42 @@ namespace GalaSoft.MvvmLight.Command
/// Initializes a new instance of the RelayCommand class that
/// can always execute.
/// </summary>
/// <param name="execute">The execution logic. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
/// <param name="execute">The execution logic. IMPORTANT: If the action causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is causing a closure. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
/// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
public RelayCommand(Action<T> execute)
: this(execute, null)
public RelayCommand(Action<T> execute, bool keepTargetAlive = false)
: this(execute, null, keepTargetAlive)
{
}
/// <summary>
/// Initializes a new instance of the RelayCommand class.
/// </summary>
/// <param name="execute">The execution logic. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
/// <param name="canExecute">The execution status logic. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
/// <param name="execute">The execution logic. IMPORTANT: If the action causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="canExecute">The execution status logic. IMPORTANT: If the func causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is causing a closure. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
/// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
public RelayCommand(Action<T> execute, Func<T, bool> canExecute)
public RelayCommand(Action<T> execute, Func<T, bool> canExecute, bool keepTargetAlive = false)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
_execute = new WeakAction<T>(execute);
_execute = new WeakAction<T>(execute, keepTargetAlive);
if (canExecute != null)
{
_canExecute = new WeakFunc<T,bool>(canExecute);
_canExecute = new WeakFunc<T,bool>(canExecute, keepTargetAlive);
}
}

Просмотреть файл

@ -25,8 +25,8 @@ namespace GalaSoft.MvvmLight.Helpers
/// to be created to the Action's owner. The owner can be garbage collected at any time.
/// </summary>
////[ClassInfo(typeof(WeakAction),
//// VersionString = "5.1.16",
//// DateString = "201502072030",
//// VersionString = "5.4.18",
//// DateString = "201708281410",
//// Description = "A class allowing to store and invoke actions without keeping a hard reference to the action's target.",
//// UrlContacts = "http://www.galasoft.ch/contact_en.html",
//// Email = "laurent@galasoft.ch")]
@ -93,6 +93,17 @@ namespace GalaSoft.MvvmLight.Helpers
set;
}
/// <summary>
/// Saves the <see cref="ActionReference"/> as a hard reference. This is
/// used in relation with this instance's constructor and only if
/// the constructor's keepTargetAlive parameter is true.
/// </summary>
protected object LiveReference
{
get;
set;
}
/// <summary>
/// Gets or sets a WeakReference to the target passed when constructing
/// the WeakAction. This is not necessarily the same as
@ -132,8 +143,12 @@ namespace GalaSoft.MvvmLight.Helpers
/// Initializes a new instance of the <see cref="WeakAction" /> class.
/// </summary>
/// <param name="action">The action that will be associated to this instance.</param>
public WeakAction(Action action)
: this(action == null ? null : action.Target, action)
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
public WeakAction(Action action, bool keepTargetAlive = false)
: this(action == null ? null : action.Target, action, keepTargetAlive)
{
}
@ -142,12 +157,16 @@ namespace GalaSoft.MvvmLight.Helpers
/// </summary>
/// <param name="target">The action's owner.</param>
/// <param name="action">The action that will be associated to this instance.</param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
[SuppressMessage(
"Microsoft.Design",
"Microsoft.Design",
"CA1062:Validate arguments of public methods",
MessageId = "1",
Justification = "Method should fail with an exception if action is null.")]
public WeakAction(object target, Action action)
public WeakAction(object target, Action action, bool keepTargetAlive = false)
{
#if NETFX_CORE
if (action.GetMethodInfo().IsStatic)
@ -189,6 +208,7 @@ namespace GalaSoft.MvvmLight.Helpers
{
Method = action.Method;
ActionReference = new WeakReference(action.Target);
LiveReference = keepTargetAlive ? action.Target : null;
}
}
#else
@ -200,7 +220,24 @@ namespace GalaSoft.MvvmLight.Helpers
ActionReference = new WeakReference(action.Target);
#endif
LiveReference = keepTargetAlive ? action.Target : null;
Reference = new WeakReference(target);
#if DEBUG
if (ActionReference != null
&& ActionReference.Target != null
&& !keepTargetAlive)
{
var type = ActionReference.Target.GetType();
if (type.Name.StartsWith("<>")
&& type.Name.Contains("DisplayClass"))
{
System.Diagnostics.Debug.WriteLine(
"You are attempting to register a lambda with a closure without using keepTargetAlive. Are you sure? Check http://galasoft.ch/s/mvvmweakaction for more info.");
}
}
#endif
}
/// <summary>
@ -212,7 +249,8 @@ namespace GalaSoft.MvvmLight.Helpers
get
{
if (_staticAction == null
&& Reference == null)
&& Reference == null
&& LiveReference == null)
{
return false;
}
@ -227,7 +265,19 @@ namespace GalaSoft.MvvmLight.Helpers
return true;
}
return Reference.IsAlive;
// Non static action
if (LiveReference != null)
{
return true;
}
if (Reference != null)
{
return Reference.IsAlive;
}
return false;
}
}
@ -255,6 +305,11 @@ namespace GalaSoft.MvvmLight.Helpers
{
get
{
if (LiveReference != null)
{
return LiveReference;
}
if (ActionReference == null)
{
return null;
@ -281,11 +336,12 @@ namespace GalaSoft.MvvmLight.Helpers
if (IsAlive)
{
if (Method != null
&& ActionReference != null
&& (LiveReference != null
|| ActionReference != null)
&& actionTarget != null)
{
Method.Invoke(actionTarget, null);
// ReSharper disable RedundantJumpStatement
return;
// ReSharper restore RedundantJumpStatement
@ -307,6 +363,7 @@ namespace GalaSoft.MvvmLight.Helpers
{
Reference = null;
ActionReference = null;
LiveReference = null;
Method = null;
_staticAction = null;

Просмотреть файл

@ -15,9 +15,9 @@
using System;
using System.Diagnostics.CodeAnalysis;
// ReSharper disable RedundantUsingDirective
using System.Reflection;
// ReSharper restore RedundantUsingDirective
namespace GalaSoft.MvvmLight.Helpers
@ -101,8 +101,12 @@ namespace GalaSoft.MvvmLight.Helpers
/// Initializes a new instance of the WeakAction class.
/// </summary>
/// <param name="action">The action that will be associated to this instance.</param>
public WeakAction(Action<T> action)
: this(action == null ? null : action.Target, action)
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
public WeakAction(Action<T> action, bool keepTargetAlive = false)
: this(action == null ? null : action.Target, action, keepTargetAlive)
{
}
@ -111,12 +115,16 @@ namespace GalaSoft.MvvmLight.Helpers
/// </summary>
/// <param name="target">The action's owner.</param>
/// <param name="action">The action that will be associated to this instance.</param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
[SuppressMessage(
"Microsoft.Design",
"CA1062:Validate arguments of public methods",
"Microsoft.Design",
"CA1062:Validate arguments of public methods",
MessageId = "1",
Justification = "Method should fail with an exception if action is null.")]
public WeakAction(object target, Action<T> action)
public WeakAction(object target, Action<T> action, bool keepTargetAlive = false)
{
#if NETFX_CORE
if (action.GetMethodInfo().IsStatic)
@ -157,6 +165,7 @@ namespace GalaSoft.MvvmLight.Helpers
{
Method = action.Method;
ActionReference = new WeakReference(action.Target);
LiveReference = keepTargetAlive ? action.Target : null;
}
}
#else
@ -168,7 +177,24 @@ namespace GalaSoft.MvvmLight.Helpers
ActionReference = new WeakReference(action.Target);
#endif
LiveReference = keepTargetAlive ? action.Target : null;
Reference = new WeakReference(target);
#if DEBUG
if (ActionReference != null
&& ActionReference.Target != null
&& !keepTargetAlive)
{
var type = ActionReference.Target.GetType();
if (type.Name.StartsWith("<>")
&& type.Name.Contains("DisplayClass"))
{
System.Diagnostics.Debug.WriteLine(
"You are attempting to register a lambda with a closure without using keepTargetAlive. Are you sure? Check http://galasoft.ch/s/mvvmweakaction for more info.");
}
}
#endif
}
/// <summary>
@ -198,7 +224,8 @@ namespace GalaSoft.MvvmLight.Helpers
if (IsAlive)
{
if (Method != null
&& ActionReference != null
&& (LiveReference != null
|| ActionReference != null)
&& actionTarget != null)
{
Method.Invoke(
@ -228,7 +255,7 @@ namespace GalaSoft.MvvmLight.Helpers
/// being casted to T.</param>
public void ExecuteWithObject(object parameter)
{
var parameterCasted = (T) parameter;
var parameterCasted = (T)parameter;
Execute(parameterCasted);
}

Просмотреть файл

@ -105,6 +105,17 @@ namespace GalaSoft.MvvmLight.Helpers
set;
}
/// <summary>
/// Saves the <see cref="FuncReference"/> as a hard reference. This is
/// used in relation with this instance's constructor and only if
/// the constructor's keepTargetAlive parameter is true.
/// </summary>
protected object LiveReference
{
get;
set;
}
/// <summary>
/// Gets or sets a WeakReference to the target passed when constructing
/// the WeakFunc. This is not necessarily the same as
@ -128,8 +139,12 @@ namespace GalaSoft.MvvmLight.Helpers
/// Initializes a new instance of the WeakFunc class.
/// </summary>
/// <param name="func">The Func that will be associated to this instance.</param>
public WeakFunc(Func<TResult> func)
: this(func == null ? null : func.Target, func)
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
public WeakFunc(Func<TResult> func, bool keepTargetAlive = false)
: this(func == null ? null : func.Target, func, keepTargetAlive)
{
}
@ -138,12 +153,16 @@ namespace GalaSoft.MvvmLight.Helpers
/// </summary>
/// <param name="target">The Func's owner.</param>
/// <param name="func">The Func that will be associated to this instance.</param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
[SuppressMessage(
"Microsoft.Design",
"Microsoft.Design",
"CA1062:Validate arguments of public methods",
MessageId = "1",
Justification = "Method should fail with an exception if func is null.")]
public WeakFunc(object target, Func<TResult> func)
public WeakFunc(object target, Func<TResult> func, bool keepTargetAlive = false)
{
#if NETFX_CORE
if (func.GetMethodInfo().IsStatic)
@ -185,6 +204,7 @@ namespace GalaSoft.MvvmLight.Helpers
{
Method = func.Method;
FuncReference = new WeakReference(func.Target);
LiveReference = keepTargetAlive ? func.Target : null;
}
}
#else
@ -196,7 +216,24 @@ namespace GalaSoft.MvvmLight.Helpers
FuncReference = new WeakReference(func.Target);
#endif
LiveReference = keepTargetAlive ? func.Target : null;
Reference = new WeakReference(target);
#if DEBUG
if (FuncReference != null
&& FuncReference.Target != null
&& !keepTargetAlive)
{
var type = FuncReference.Target.GetType();
if (type.Name.StartsWith("<>")
&& type.Name.Contains("DisplayClass"))
{
System.Diagnostics.Debug.WriteLine(
"You are attempting to register a lambda with a closure without using keepTargetAlive. Are you sure? Check http://galasoft.ch/s/mvvmweakaction for more info.");
}
}
#endif
}
/// <summary>
@ -208,7 +245,8 @@ namespace GalaSoft.MvvmLight.Helpers
get
{
if (_staticFunc == null
&& Reference == null)
&& Reference == null
&& LiveReference == null)
{
return false;
}
@ -223,7 +261,19 @@ namespace GalaSoft.MvvmLight.Helpers
return true;
}
return Reference.IsAlive;
// Non static action
if (LiveReference != null)
{
return true;
}
if (Reference != null)
{
return Reference.IsAlive;
}
return false;
}
}
@ -254,6 +304,11 @@ namespace GalaSoft.MvvmLight.Helpers
{
get
{
if (LiveReference != null)
{
return LiveReference;
}
if (FuncReference == null)
{
return null;
@ -280,7 +335,8 @@ namespace GalaSoft.MvvmLight.Helpers
if (IsAlive)
{
if (Method != null
&& FuncReference != null
&& (LiveReference != null
|| FuncReference != null)
&& funcTarget != null)
{
return (TResult)Method.Invoke(funcTarget, null);
@ -304,6 +360,7 @@ namespace GalaSoft.MvvmLight.Helpers
{
Reference = null;
FuncReference = null;
LiveReference = null;
Method = null;
_staticFunc = null;

Просмотреть файл

@ -102,8 +102,12 @@ namespace GalaSoft.MvvmLight.Helpers
/// Initializes a new instance of the WeakFunc class.
/// </summary>
/// <param name="func">The Func that will be associated to this instance.</param>
public WeakFunc(Func<T, TResult> func)
: this(func == null ? null : func.Target, func)
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
public WeakFunc(Func<T, TResult> func, bool keepTargetAlive = false)
: this(func == null ? null : func.Target, func, keepTargetAlive)
{
}
@ -112,12 +116,16 @@ namespace GalaSoft.MvvmLight.Helpers
/// </summary>
/// <param name="target">The Func's owner.</param>
/// <param name="func">The Func that will be associated to this instance.</param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
[SuppressMessage(
"Microsoft.Design",
"CA1062:Validate arguments of public methods",
MessageId = "1",
Justification = "Method should fail with an exception if func is null.")]
public WeakFunc(object target, Func<T, TResult> func)
public WeakFunc(object target, Func<T, TResult> func, bool keepTargetAlive = false)
{
#if NETFX_CORE
if (func.GetMethodInfo().IsStatic)
@ -158,6 +166,7 @@ namespace GalaSoft.MvvmLight.Helpers
{
Method = func.Method;
FuncReference = new WeakReference(func.Target);
LiveReference = keepTargetAlive ? func.Target : null;
}
}
#else
@ -169,7 +178,24 @@ namespace GalaSoft.MvvmLight.Helpers
FuncReference = new WeakReference(func.Target);
#endif
LiveReference = keepTargetAlive ? func.Target : null;
Reference = new WeakReference(target);
#if DEBUG
if (FuncReference != null
&& FuncReference.Target != null
&& !keepTargetAlive)
{
var type = FuncReference.Target.GetType();
if (type.Name.StartsWith("<>")
&& type.Name.Contains("DisplayClass"))
{
System.Diagnostics.Debug.WriteLine(
"You are attempting to register a lambda with a closure without using keepTargetAlive. Are you sure? Check http://galasoft.ch/s/mvvmweakaction for more info.");
}
}
#endif
}
/// <summary>
@ -200,7 +226,8 @@ namespace GalaSoft.MvvmLight.Helpers
if (IsAlive)
{
if (Method != null
&& FuncReference != null
&& (LiveReference != null
|| FuncReference != null)
&& funcTarget != null)
{
return (TResult) Method.Invoke(

Просмотреть файл

@ -38,7 +38,14 @@ namespace GalaSoft.MvvmLight.Messaging
/// <param name="action">The action that will be executed when a message
/// of type TMessage is sent. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
void Register<TMessage>(object recipient, Action<TMessage> action);
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
void Register<TMessage>(
object recipient,
Action<TMessage> action,
bool keepTargetAlive = false);
/// <summary>
/// Registers a recipient for a type of message TMessage.
@ -59,9 +66,16 @@ namespace GalaSoft.MvvmLight.Messaging
/// get the message. Similarly, messages sent without any token, or with a different
/// token, will not be delivered to that recipient.</param>
/// <param name="action">The action that will be executed when a message
/// of type TMessage is sent. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
void Register<TMessage>(object recipient, object token, Action<TMessage> action);
/// of type TMessage is sent.</param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
void Register<TMessage>(
object recipient,
object token,
Action<TMessage> action,
bool keepTargetAlive = false);
/// <summary>
/// Registers a recipient for a type of message TMessage.
@ -93,9 +107,17 @@ namespace GalaSoft.MvvmLight.Messaging
/// and ExecuteOrderMessage to the recipient that registered.</para>
/// </param>
/// <param name="action">The action that will be executed when a message
/// of type TMessage is sent. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
void Register<TMessage>(object recipient, object token, bool receiveDerivedMessagesToo, Action<TMessage> action);
/// of type TMessage is sent.</param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
void Register<TMessage>(
object recipient,
object token,
bool receiveDerivedMessagesToo,
Action<TMessage> action,
bool keepTargetAlive = false);
/// <summary>
/// Registers a recipient for a type of message TMessage.
@ -121,9 +143,16 @@ namespace GalaSoft.MvvmLight.Messaging
/// and ExecuteOrderMessage to the recipient that registered.</para>
/// </param>
/// <param name="action">The action that will be executed when a message
/// of type TMessage is sent. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
void Register<TMessage>(object recipient, bool receiveDerivedMessagesToo, Action<TMessage> action);
/// of type TMessage is sent.</param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
void Register<TMessage>(
object recipient,
bool receiveDerivedMessagesToo,
Action<TMessage> action,
bool keepTargetAlive = false);
/// <summary>
/// Sends a message to registered recipients. The message will

Просмотреть файл

@ -43,8 +43,8 @@ namespace GalaSoft.MvvmLight.Messaging
/// The Messenger is a class allowing objects to exchange messages.
/// </summary>
////[ClassInfo(typeof(Messenger),
//// VersionString = "5.3.19",
//// DateString = "201604212130",
//// VersionString = "5.4.21",
//// DateString = "201708281410",
//// Description = "A messenger class allowing a class to send a message to multiple recipients",
//// UrlContacts = "http://www.galasoft.ch/contact_en.html",
//// Email = "laurent@galasoft.ch")]
@ -95,11 +95,18 @@ namespace GalaSoft.MvvmLight.Messaging
/// for.</typeparam>
/// <param name="recipient">The recipient that will receive the messages.</param>
/// <param name="action">The action that will be executed when a message
/// of type TMessage is sent. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
public virtual void Register<TMessage>(object recipient, Action<TMessage> action)
/// of type TMessage is sent. IMPORTANT: If the action causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
public virtual void Register<TMessage>(
object recipient,
Action<TMessage> action,
bool keepTargetAlive = false)
{
Register(recipient, null, false, action);
Register(recipient, null, false, action, keepTargetAlive);
}
/// <summary>
@ -110,35 +117,8 @@ namespace GalaSoft.MvvmLight.Messaging
/// messages implementing TMessage) can be received too.
/// <para>Registering a recipient does not create a hard reference to it,
/// so if this recipient is deleted, no memory leak is caused.</para>
/// </summary>
/// <typeparam name="TMessage">The type of message that the recipient registers
/// for.</typeparam>
/// <param name="recipient">The recipient that will receive the messages.</param>
/// <param name="receiveDerivedMessagesToo">If true, message types deriving from
/// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage
/// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage
/// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
/// and ExecuteOrderMessage to the recipient that registered.
/// <para>Also, if TMessage is an interface, message types implementing TMessage will also be
/// transmitted to the recipient. For example, if a SendOrderMessage
/// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage
/// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
/// and ExecuteOrderMessage to the recipient that registered.</para>
/// </param>
/// <param name="action">The action that will be executed when a message
/// of type TMessage is sent. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
public virtual void Register<TMessage>(object recipient, bool receiveDerivedMessagesToo, Action<TMessage> action)
{
Register(recipient, null, receiveDerivedMessagesToo, action);
}
/// <summary>
/// Registers a recipient for a type of message TMessage.
/// The action parameter will be executed when a corresponding
/// message is sent.
/// <para>Registering a recipient does not create a hard reference to it,
/// so if this recipient is deleted, no memory leak is caused.</para>
/// <para>However if you use closures and set keepTargetAlive to true, you might
/// cause a memory leak if you don't call <see cref="Unregister"/> when you are cleaning up.</para>
/// </summary>
/// <typeparam name="TMessage">The type of message that the recipient registers
/// for.</typeparam>
@ -150,11 +130,19 @@ namespace GalaSoft.MvvmLight.Messaging
/// get the message. Similarly, messages sent without any token, or with a different
/// token, will not be delivered to that recipient.</param>
/// <param name="action">The action that will be executed when a message
/// of type TMessage is sent. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
public virtual void Register<TMessage>(object recipient, object token, Action<TMessage> action)
/// of type TMessage is sent. IMPORTANT: If the action causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
public virtual void Register<TMessage>(
object recipient,
object token,
Action<TMessage> action,
bool keepTargetAlive = false)
{
Register(recipient, token, false, action);
Register(recipient, token, false, action, keepTargetAlive);
}
/// <summary>
@ -187,13 +175,18 @@ namespace GalaSoft.MvvmLight.Messaging
/// and ExecuteOrderMessage to the recipient that registered.</para>
/// </param>
/// <param name="action">The action that will be executed when a message
/// of type TMessage is sent. IMPORTANT: Note that closures are not supported at the moment
/// due to the use of WeakActions (see http://stackoverflow.com/questions/25730530/). </param>
/// of type TMessage is sent. IMPORTANT: If the action causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
public virtual void Register<TMessage>(
object recipient,
object token,
bool receiveDerivedMessagesToo,
Action<TMessage> action)
Action<TMessage> action,
bool keepTargetAlive = false)
{
lock (_registerLock)
{
@ -234,7 +227,7 @@ namespace GalaSoft.MvvmLight.Messaging
list = recipients[messageType];
}
var weakAction = new WeakAction<TMessage>(recipient, action);
var weakAction = new WeakAction<TMessage>(recipient, action, keepTargetAlive);
var item = new WeakActionAndToken
{
@ -249,6 +242,45 @@ namespace GalaSoft.MvvmLight.Messaging
RequestCleanup();
}
/// <summary>
/// Registers a recipient for a type of message TMessage.
/// The action parameter will be executed when a corresponding
/// message is sent. See the receiveDerivedMessagesToo parameter
/// for details on how messages deriving from TMessage (or, if TMessage is an interface,
/// messages implementing TMessage) can be received too.
/// <para>Registering a recipient does not create a hard reference to it,
/// so if this recipient is deleted, no memory leak is caused.</para>
/// </summary>
/// <typeparam name="TMessage">The type of message that the recipient registers
/// for.</typeparam>
/// <param name="recipient">The recipient that will receive the messages.</param>
/// <param name="receiveDerivedMessagesToo">If true, message types deriving from
/// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage
/// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage
/// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
/// and ExecuteOrderMessage to the recipient that registered.
/// <para>Also, if TMessage is an interface, message types implementing TMessage will also be
/// transmitted to the recipient. For example, if a SendOrderMessage
/// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage
/// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
/// and ExecuteOrderMessage to the recipient that registered.</para>
/// </param>
/// <param name="action">The action that will be executed when a message
/// of type TMessage is sent. IMPORTANT: If the action causes a closure,
/// you must set keepTargetAlive to true to avoid side effects. </param>
/// <param name="keepTargetAlive">If true, the target of the Action will
/// be kept as a hard reference, which might cause a memory leak. You should only set this
/// parameter to true if the action is using closures. See
/// http://galasoft.ch/s/mvvmweakaction. </param>
public virtual void Register<TMessage>(
object recipient,
bool receiveDerivedMessagesToo,
Action<TMessage> action,
bool keepTargetAlive = false)
{
Register(recipient, null, receiveDerivedMessagesToo, action, keepTargetAlive);
}
private bool _isCleanupRegistered;
/// <summary>