Skip to content

Commit

Permalink
(GH-17) Added simple class for wrapping other classes
Browse files Browse the repository at this point in the history
  • Loading branch information
AdmiringWorm committed Jul 21, 2020
1 parent 51ad9e3 commit da0b54f
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 9 deletions.
35 changes: 30 additions & 5 deletions Cake.Issues.Recipe/Content/loader/AddinData.cake
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class AddinData
public IList<TypeInfo> _definedClasses = new List<TypeInfo>();
private IList<MethodInfo> _definedMethods = new List<MethodInfo>();

public object CreateClass(string classTypeString, params object[] parameters)
public ClassWrapper CreateClass(string classTypeString, params object[] parameters)
{
var possibleClass = _definedClasses.FirstOrDefault(c => string.Compare(c.Name, classTypeString, StringComparison.OrdinalIgnoreCase) == 0);

Expand All @@ -28,7 +28,7 @@ public class AddinData
return CreateClass(possibleClass, parameters);
}

public object CreateClass(TypeInfo classType, params object[] parameters)
public ClassWrapper CreateClass(TypeInfo classType, params object[] parameters)
{
parameters = parameters ?? new object[0];
var constructors = classType.DeclaredConstructors.Where(c => c.IsPublic && !c.IsStatic && c.GetParameters().Length == parameters.Length);
Expand All @@ -51,10 +51,24 @@ public class AddinData
throw new NullReferenceException("No valid constructor was found!");
}

return constructor.Invoke(parameters ?? new object[0]);
var result = constructor.Invoke(parameters ?? new object[0]);

return new ClassWrapper(result, this);
}

public TType CallStaticMethod<TType>(string methodName, params object[] parameters)
{
var result = CallStaticMethod(methodName, parameters);

if (result.GetType().IsClass)
{
return (TType)result.ToActual();
}

return (TType)result;
}

public object CallStaticMethod(string methodName, params object[] parameters)
public dynamic CallStaticMethod(string methodName, params object[] parameters)
{
parameters = TransformParameters(parameters);

Expand All @@ -78,7 +92,14 @@ public class AddinData
throw new NullReferenceException($"No method with the name '{methodName}' was found!");
}

return method.Invoke(null, parameters);
var result = method.Invoke(null, parameters);

if (result.GetType().IsClass)
{
return new ClassWrapper(result, this);
}

return result;
}

public object[] TransformParameters(params object[] parameters)
Expand Down Expand Up @@ -112,6 +133,10 @@ public class AddinData
}
}
}
else if (parameter is ClassWrapper wrapper)
{
value = wrapper.ToActual();
}

newParameters.Add(value);
}
Expand Down
89 changes: 89 additions & 0 deletions Cake.Issues.Recipe/Content/loader/ClassWrapper.cake
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System.Reflection;

public sealed class ClassWrapper
{
private readonly Type _classType;
private readonly object _concreteClass;
private readonly AddinData _addinData;

public ClassWrapper(object concreteClass, AddinData addinData)
{
var classType = concreteClass.GetType();

if (!classType.IsClass)
{
throw new Exception($"The class {classType.Name} is not a class type!");
}

_concreteClass = concreteClass;
_addinData = addinData;
_classType = classType;
}

public object GetPropertyValue(string propertyName)
{
var property = _classType.GetProperty(propertyName, BindingFlags.GetProperty | BindingFlags.Public);

return property.GetValue(_concreteClass);
}

public void SetPropertyValue(string propertyName, object value)
{
var property = _classType.GetProperty(propertyName, BindingFlags.SetProperty | BindingFlags.Public);
value = _addinData.TransformParameters(value).First();
if (property.PropertyType.IsEnum && !value.GetType().IsEnum)
{
value = Enum.Parse(property.PropertyType, value.ToString());
}

property.SetValue(_concreteClass, value);
}

public dynamic CallExtensionMethod(string methodName, params object[] parameters)
{
var newParameters = new List<object>();
newParameters.Add(_concreteClass);
newParameters.AddRange(_addinData.TransformParameters(parameters));

return _addinData.CallStaticMethod(methodName, newParameters.ToArray());
}

public dynamic CallMethod(string methodName, params object[] parameters)
{
parameters = _addinData.TransformParameters(parameters);

var methods = _classType.GetMethods(BindingFlags.Instance | BindingFlags.Public).Where(m => string.Compare(m.Name, methodName, StringComparison.OrdinalIgnoreCase) == 0);
MethodInfo method = null;

foreach (var m in methods.Where(m => m.GetParameters().Length == parameters.Length))
{
var methodParams = m.GetParameters();
bool useMethod = AddinData.ParametersMatch(methodParams, parameters);

if (useMethod)
{
method = m;
break;
}
}

if (method is null)
{
throw new NullReferenceException($"No method with the name '{methodName}' was found in the class '{_classType.Name}'");
}

var result = method.Invoke(_concreteClass, parameters);

if (result.GetType().IsClass)
{
return new ClassWrapper(result, _addinData);
}

return result;
}

public object ToActual()
{
return _concreteClass;
}
}
3 changes: 2 additions & 1 deletion Cake.Issues.Recipe/Content/loader/loader.cake
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#load ./AddinData.cake
#load ./AddinData.cake
#load ./ClassWrapper.cake
6 changes: 3 additions & 3 deletions Cake.Issues.Recipe/Content/reporters/GenericReporterData.cake
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public class GenericReporterData : AddinData
var settings = reporter.CallStaticMethod("FromEmbeddedTemplate", "HtmlDxDataGrid");

var theme = "DevExtremeTheme.MaterialBlueLight"; // Should be changed to be set on IssuesParametersReporting settings class.
reporter.CallStaticMethod("WithOption", settings, "HtmlDxDataGridOption.Theme", theme);
settings.CallExtensionMethod("WithOption", "HtmlDxDataGridOption.Theme", theme);

var issueFormat = (IIssueReportFormat)reporter.CallStaticMethod("GenericIssueReportFormat", context, settings);
var issueFormat = reporter.CallStaticMethod<IIssueReportFormat>("GenericIssueReportFormat", context, settings);

return issueFormat;
}
Expand All @@ -31,7 +31,7 @@ public class GenericReporterData : AddinData
{
var reporter = GetReporter(context);

var issueFormat = (IIssueReportFormat)reporter.CallStaticMethod("GenericIssueReportFormatFromFilePath", context, reportPath);
var issueFormat = reporter.CallStaticMethod<IIssueReportFormat>("GenericIssueReportFormatFromFilePath", context, reportPath);

return issueFormat;
}
Expand Down

0 comments on commit da0b54f

Please sign in to comment.