C# MSBuild:描述要调用的构造函数
我正在处理一个需要实例化类的MSBuild任务。该类最初只有一个无参数构造函数,因此所需的所有MSBuild任务都是实例化该类的类型名。现在我们有了一个针对特定构造函数运行任务的用例,我不知道如何以通用方式处理这个问题。假设我需要实例化不同风格的C# MSBuild:描述要调用的构造函数,c#,.net,msbuild,msbuild-task,C#,.net,Msbuild,Msbuild Task,我正在处理一个需要实例化类的MSBuild任务。该类最初只有一个无参数构造函数,因此所需的所有MSBuild任务都是实例化该类的类型名。现在我们有了一个针对特定构造函数运行任务的用例,我不知道如何以通用方式处理这个问题。假设我需要实例化不同风格的ClassA: public class ClassA { public ClassA() { } public ClassA(int someArgument) { } public ClassA(int someArgumen
ClassA
:
public class ClassA
{
public ClassA() { }
public ClassA(int someArgument) { }
public ClassA(int someArgument, bool someOtherArgument) { }
}
原来的任务是这样的:
<DoSomethingTask Assembly="ContainsClassA.dll" Type="ClassA" />
我的理想任务如下所示,因此我可以调用任何以基元类型作为参数的构造函数:
<DoSomethingTask Assembly="ContainsClassA.dll" Type="ClassA">
<ConstructorArgs>
<Arg type="int">1</Arg>
<Arg type="bool">True</Arg>
</ConstructorArgs>
</DoSomethingTask>
1.
真的
我非常不知道要搜索什么才能获得这种类型的功能。我可以做一些事情,比如创建一个名为ConstructorArgs
的字符串属性,并使用我想要的任何格式对其进行解析,但我希望有更干净的东西存在。谢谢你能提供的任何帮助
编辑-如果有人想知道,我试图修改的实际任务会基于实例化的实体框架DbContext创建一个预生成的视图。我们有自己的DbContext子类和各种构造函数,我们希望能够在视图生成过程中调用特定的构造函数。您可以尝试为DbContext子类调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace TaskClass
{
// Class to be created
public class MyDbContext
{
public int ConstructorArg1 { get; set; }
public string ConstructorArg2 { get; set; }
public MyDbContext() { }
public MyDbContext(int constructorArg1)
{
ConstructorArg1 = constructorArg1;
}
public MyDbContext(int constructorArg1, string constructorArg2)
{
ConstructorArg1 = constructorArg1;
ConstructorArg2 = constructorArg2;
}
}
// MSBuild custom task
public class DoSomethingTask : Task
{
public override bool Execute()
{
var taskParameters = new TaskParametersInfo();
taskParameters.ExtractTaskParametersInfo(this);
var type = typeof(MyDbContext);
ConstructorInfo ctor = type.GetConstructor(taskParameters.Types.ToArray());
if (ctor == null)
{
// If the constructor is not found, throw an error
Log.LogError("There are no constructors defined with these parameters.");
return false;
}
// Create your instance
var myDbContext = (MyDbContext)ctor.Invoke(taskParameters.Values.ToArray());
return true;
}
public int ConstructorArg1
{
get;
set;
}
public string ConstructorArg2
{
get;
set;
}
public string ConstructorArg3
{
get;
set;
}
// Class to handle the task's parameters
internal class TaskParametersInfo
{
public List<Type> Types { get; set; }
public List<object> Values { get; set; }
public TaskParametersInfo()
{
Types = new List<Type>();
Values = new List<object>();
}
public void ExtractTaskParametersInfo(Task task)
{
foreach (var property in task.GetType().GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
{
var propertyValue = property.GetValue(task, null);
if (propertyValue != null)
{
Types.Add(property.PropertyType);
Values.Add(propertyValue);
}
}
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
运用系统反思;
使用系统文本;
使用Microsoft.Build.Framework;
使用Microsoft.Build.Utilities;
命名空间任务类
{
//要创建的类
公共类MyDbContext
{
公共int构造函数arg1{get;set;}
公共字符串构造函数arg2{get;set;}
公共MyDbContext(){}
公共MyDbContext(int构造函数arg1)
{
ConstructorArg1=ConstructorArg1;
}
公共MyDbContext(int构造函数arg1、字符串构造函数arg2)
{
ConstructorArg1=ConstructorArg1;
ConstructorArg2=ConstructorArg2;
}
}
//MSBuild自定义任务
公共类DoSomethingTask:任务
{
公共重写bool Execute()
{
var taskParameters=new TaskParametersInfo();
taskParameters.ExtractTaskParametersInfo(此);
var type=typeof(MyDbContext);
ConstructorInfo-ctor=type.GetConstructor(taskParameters.Types.ToArray());
if(ctor==null)
{
//如果未找到构造函数,则抛出错误
LogError(“没有使用这些参数定义的构造函数”);
返回false;
}
//创建您的实例
var myDbContext=(myDbContext)ctor.Invoke(taskParameters.Values.ToArray());
返回true;
}
公共int构造函数arg1
{
得到;
设置
}
公共字符串构造函数arg2
{
得到;
设置
}
公共字符串构造函数arg3
{
得到;
设置
}
//类来处理任务的参数
内部类TaskParametersInfo
{
公共列表类型{get;set;}
公共列表值{get;set;}
公共任务参数sinfo()
{
类型=新列表();
值=新列表();
}
public void ExtractTaskParametersInfo(任务任务)
{
foreach(task.GetType().GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)中的var属性)
{
var propertyValue=property.GetValue(任务,空);
if(propertyValue!=null)
{
添加(property.PropertyType);
添加(propertyValue);
}
}
}
}
}
}
导入msbuild项目上的任务:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project ToolsVersion="4.0" defaultTarget="DoSomething" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="TaskClass.DoSomethingTask"
AssemblyFile="TaskClass\TaskClass\bin\Debug\TaskClass.dll"/>
<Target Name="DoSomething">
<DoSomethingTask ConstructorArg1="123" ConstructorArg2="Are u talking to me?" />
</Target>
</Project>
希望这能有所帮助。这与我在任务中实际要做的类似,但我试图解决的问题涉及数量未知的各种类型的参数。所以我可能有这样的构造函数:(string,int,int),(string,bool),(string,bool,bool)。我更想了解如何在具有基元类型描述符的字符串的MSBuild中提供数组。