[英]Alternative to Call abstract method in base class constructor
我的问题是这样的:
我有一个基础课
public abstract class ViewModelBase
其中包含抽象方法“ RegisterCommands”
protected abstract void RegisterCommands();
很显然,我所有的派生类都必须实现此方法,例如我的LoginViewModel具有
protected override void RegisterCommands()
{
LoginCommand?
.Configure(
execute: (msg) => { Login(User); },
canExecute: (x) => { return CanLogin(); }
);
}
并在实例化类时调用它,但是我不想在每个派生类构造函数中调用此方法(如果我有100个派生类,我必须调用RegisterCommand 100次)。
正常的解决方案是在基类构造函数中调用RegisterCommand
protected abstract void RegisterCommands();
public ViewModelBase()
{
RegisterCommands();
}
这通常是可行的(即使我不知道这是否是个好习惯),但是...但是...
在我的场景中,在所有RegisterCommands方法中,我都使用ICustomCommand对象,这些对象在依赖项注入的派生类构造函数中初始化
public class LoginViewModel : ViewModelBase
{
private ICustomCommand _loginCommand;
public ICustomCommand LoginCommand
{
get
{
return _loginCommand;
}
set
{
_loginCommand = value;
}
}
public LoginViewModel(ICustomCommand loginCommand)
{
_loginCommand = loginCommand;
}
protected override void RegisterCommands()
{
LoginCommand?
.Configure(
execute: (msg) => { Login(User); },
canExecute: (x) => { return CanLogin(); }
);
}
因此,由于基类构造函数在派生类构造函数之前被调用,因此我无法在基类构造函数中调用RegisterCommands()(因为我的ICustomCommands尚未在派生类中初始化,因此RegisterCommands()尝试使用仍为null的ICustomCommand) 。
我知道不可能在基类构造函数之前调用派生类构造函数,那么在仅一处调用此命令的所有派生类中调用RegisterCommands的有效,简单,简洁的解决方案是什么?
谢谢你的回答
更新:
如我所说,RegisterCommands()是复数的,因为每个派生类都可以有N个ICustomCommand对象
所以我可以有
我的LoginViewModel的LoginCommand
SaveCommand,另一个ViewModel的DeleteCommand
等等
我现在认为的一种解决方案是从构造函数中删除ICustomCommand初始化并通过静态Resolver类在getter属性中“即时”解决它。
public ICustomCommand LoginCommand
{
get
{
if(_loginCommand == null)
MyStaticResolver.Resolve<ICustomCommand>();
return _loginCommand;
但我仍然不相信
如果使用接口表示命令,则可以将它们传递给基类,并公开一种方法来检索命令。 然后,您的注册方法可以根据需要使用它们:
public abstract class ViewModelBase
{
public ViewModelBase(params ICustomCommand[] commands)
{
_commands = commands;
RegisterCommands();
}
private IEnumerable<ICustomCommand> _commands;
protected abstract void RegisterCommands();
//This method gets you the commands
protected T GetCommand<T>() where T : ICustomCommand
{
var command = _commands.FirstOrDefault(c => typeof(T).IsAssignableFrom(c.GetType()));
return (T)command ;
}
}
public class LoginViewModel : ViewModelBase
{
public LoginViewModel(ILoginCommand command):base(command)
{
}
protected override void RegisterCommands()
{
//Get the command from the base class
var command = GetCommand<ILoginCommand>();
command?
.Configure(
execute: (msg) => { Login(User); },
canExecute: (x) => { return CanLogin(); }
);
}
}
public class LoginCommand : ILoginCommand
{
}
public interface ILoginCommand : ICustomCommand
{
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.