[英]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.