Activator.CreateInstance thrown Exception
Здравейте,
EDIT:
Използвам следният код за инстанциране на обекти от дадени класове
IExecutable command = (IExecutable) Activator.CreateInstance(type, args);
Абстрактният клас Command изглежда така
public abstract class Command : IExecutable
{
protected string[] arguments;
protected IDatabase database;
protected Command(string[] arguments, IDatabase database, int paramethersCount)
{
this.arguments = arguments;
this.database = database;
this.ValidateParametersCount(paramethersCount);
}
public abstract string Execute();
private void ValidateParametersCount(int count)
{
if (this.arguments.Length != count)
{
throw new InvalidOperationException(Constants.InvalidCommand);
}
}
}
Има изискване, ако на входа са подадени различен по брой параметри от необходимите, да се хвърли грешка "Invalid Command". Всеки клас, наследник на този, има константно поле с броя на аргументи, които очаква. Подава го на този конструктор и при извикване на конструктора се извиква метода ValidateParametersCount, който сравнява броя на подадените аргументи с броя на очакваните. Ако са различни хвърля InvalidOperationException. Обаче, понеже Activator-а не е успял да инстанцира, той си хвърля друга грешка TargetInvocationException и до Catch-а стига нейното съобщение, а не това на IvalidOperationException.
В момента решавам проблема по следния начин, но не ми харесва.
catch (TargetInvocationException)
{
this.userInterface.WriteLine(Constants.InvalidCommand);
}
Въпрос 1. Ок ли е в конструктора на абстрактния клас да правя проверка за броя на аргументите и ако не са равни да хвърлям грешка
Въпрос 2. Как да докарам до catch-а InvalidOperationException, а не TargetInvocationException
EDIT: Използвам поста да попитам и защо джъджа не ми харесва решението и гърми с "Compile time error"
Compiled file is missing. Compiler output: C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(1098,5): error MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.5" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend. [C:\Windows\TEMP\kkupuoqr.fxr\Air Conditioner Testing System_Skeleton\BigMani\BigMani.csproj]
Поздрави!
Здравей,
Команд интерпретъра знае само какъв тип команда да върне в зависимост от инпута. Той не знае коя команда колко параметъра очаква и ако искам да разбере, трябва да набия if else, но не ми се иска да го правя.
Поздрави!
Ами от кода който си дал разбирам , че първо сетваш arguments , след това db , и след това валидираш параметрите.
Т.е това нещо за arguments.length != parametersCount ,защо не може да е метод на CommandInterpreter?
A дори можеш чрез DependencyInjection да направиш , така че всяка команда да е с празен конструктор и да речем от CommandInterpreterа да сетваш необходимите депендънсита на всяка команда ( не знам дали всички имат еднакви) .
Но дори всички да имат еднакви , да речем в бъдеще се появява нова команда ,която ще има dependеncy само от Database ще взима нещо от там и ще го принти.
Това го има в лаба обяснено може да го видиш какво точно имам предвид.
Поздрави.
Здравей,
Т.е това нещо за arguments.length != parametersCount ,защо не може да е метод на CommandInterpreter? - Защото parametersCount е константа от клас наследник. Конструктора на клас наследник изглежда така
Ето така ми изглежда CommandInterpreter-а. Знам, че не е най - добрата имплементация, но си ми е нотка за подобрение на кода. Предложи къде в него да проверя коя команда колко аргумента да очаква.
Всеки клас си държи константа колко параметъра очаква. Ако реша да искарам тази информация извън класовете, трябва да използвам if else. if еди кой си клас, провери броя на параметрите. If друг клас... Ако се сещаш за друг начин, може да го споделиш.
Колкото до Dependency Injection-а,. Инжекта не е решение на представеня проблем. Всички команди изполват database, за това няма смисъл да я инжектвам. Ползвам инжект за една единствена команда.
Поздрави!