I always try to avoid the use of Service Locator, but in this case I have models that inherit from Base and raises events (e.g. INotifyPropertyChanged) which I want to always dispatch on the UI Thread. I can't use a DI container to keep the model constructor empty.
Below my code.
public abstract class Base
{
private static IMainThreadDispatcherService _dispatcherService;
/// <summary>
/// The main thread dispatcher.
/// </summary>
protected static IMainThreadDispatcherService DispatcherService
{
get
{
return _dispatcherService ??
(_dispatcherService = DependencyLocatorService.Resolve<IMainThreadDispatcherService>());
}
}
/// <summary>
/// Helper method to raise PropertyChanged events.
/// </summary>
/// <typeparam name="T">Type of the property.</typeparam>
/// <param name="selectorExpression">The expression to pass the property name.</param>
public virtual void OnPropertyChanged<T>(Expression<Func<T>> selectorExpression)
{
if (selectorExpression == null)
{
throw new ArgumentNullException("selectorExpression");
}
MemberExpression body = selectorExpression.Body as MemberExpression;
if (body == null)
{
throw new ArgumentException("The body must be a member expression");
}
DispatcherService.RequestMainThreadAction(() =>
{
NotifyPropertyChanged(selectorExpression);
});
}
}
/// <summary>
/// A service that holds on the UI thread dispatcher.
/// </summary>
public interface IMainThreadDispatcherService
{
/// <summary>
/// Invoke an action on main thread.
/// </summary>
/// <param name="action">The Action to invoke.</param>
/// <returns>True if successfully invoked.</returns>
bool RequestMainThreadAction(Action action);
}
/// <summary>
/// This class is an abstraction of the service locator.
/// </summary>
public class DependencyLocatorService : IDependencyLocatorService
{
/// <summary>
/// Constructs a new object instance injecting all required dependencies.
/// </summary>
/// <typeparam name="T">Type of.</typeparam>
/// <returns>The object instance constructed.</returns>
public T IocConstruct<T>()
{
// A resolver
}
/// <summary>
/// Resolves an instance of the specified type.
/// </summary>
/// <typeparam name="T">Type of.</typeparam>
/// <returns>The object instance.</returns>
public static T Resolve<T>() where T : class
{
try
{
// A resolver
}
catch(Exception)
{}
return null;
}
/// <summary>
/// Registers a singleton instance of type T.
/// </summary>
/// <typeparam name="T">The type to register.</typeparam>
/// <param name="instance">The instance.</param>
public static void RegisterSingleton<T>(T instance) where T : class
{
try
{
// A resolver
}
catch (Exception)
{
}
}
}
The problem is when I want to unit test the models that inherit from Base
things start to get difficult.
I'm seeking to change the architecture to enable proper unit testing and mock the method DispatcherService.RequestMainThreadAction
, but still raise the event.
I'm using the Moq framework and not sure if I can setup somehow this kind of mocking since I want the original Action to be invoked.