我正在尝试创建一个具有实例的Dsl 单个Dsl .rb文件,然后从CLR运行它们。
我想在IronRuby和中创建和设置Clr对象的值 然后以某种方式访问.rb Dsl实例后的CLR对象 文件已经运行。
这是我的Clr对象,目前非常简单:
namespace Horn.Core.Dsl
{
public class BuildMetaData : IBuildMetaData
{
public string Description { get; set; }
}
}
我有以下模块,我用它来指定我的Dsl和哪个 将创建上面指定的BuildMetaData实例:
module MetaBuilder
module Dsl
module Main
attr_accessor :metadata
def install(name, &block)
@metadata = Horn::Core::Dsl::BuildMetaData.new
yield self if block_given?
end
def description(desc)
@metadata.Description = desc
end
def get_metadata
@metadata
end
end
end
end
include MetaBuilder::Dsl::Main
我想以某种方式希望能够从Clr获取@metadata属性 在Dsl的实例运行后的代码。
Dsl的一个实例目前看起来像这样:
install :horn do
description "A .NET build and dependency manager"
end
我的C#代码目前看起来像这样:
var engine = Ruby.CreateEngine();
engine.Runtime.LoadAssembly(typeof(BuildMetaData).Assembly);
engine.ExecuteFile(buildFile);
var klass = engine.Runtime.Globals.GetVariable("get_metadata");
无论如何,我可以在不必使用@metadata属性 污染Dsl实例?
答案 0 :(得分:2)
对于任何有兴趣的人,我设法通过创建一个来解决这个问题 单例来容纳BuildMetaData类的实例。
我的Ruby代码最终看起来像这样:
module MetaBuilder
module Dsl
module Main
def install(name, &block)
yield self if block_given?
end
def get_from(name, url)
puts name
puts url
end
def description(desc)
meta.metadata.Description = desc
end
class MetaDataAccessor
attr_accessor :metadata
private
def initialize
@metadata = Horn::Core::Dsl::BuildMetaData.new
end
public
def self.instance
@@instance ||= new
end
def self.get_metadata
@metadata
end
end
end
end
end
def meta
MetaBuilder::Dsl::Main::MetaDataAccessor.instance
end
class ClrAccessor
def get_build_metadata
meta.metadata
end
end
include MetaBuilder::Dsl::Main
我创建了MetaDataAccessor以保留单个BuildMetaData 实例
我无法计算出C#代码来访问一个完全限定的类 嵌套在模块之间,所以我创建了ClrAccessor类 提供来自Clr的访问。
我的C#代码最终看起来像这样:
var engine = Ruby.CreateEngine();
engine.Runtime.LoadAssembly(typeof(BuildMetaData).Assembly);
engine.ExecuteFile(buildFile);
var klass = engine.Runtime.Globals.GetVariable("ClrAccessor");
var instance = engine.Operations.CreateInstance(klass);
buildMetaData = (BuildMetaData)engine.Operations.InvokeMember(instance,
"get_build_metadata");
我相信有一种更简单的方法,但对我来说这是进步。
对此“围绕房屋”方法的任何意见都将不胜感激。