在Revit 2015 + 2016中创建参数的代码相同

时间:2015-10-28 13:43:15

标签: revit revit-api

因此,2016 API中更正了Revit 2015 API中的ExternalDefinitionCreationOptions had a spelling error

我尝试使我的应用程序与当前版本+之前的版本尽可能兼容,但这次我甚至无法编译它,因为我只能引用两个API DLL中的一个,而{{1}在这个过程中起着重要作用。

代码如下:

\9

我正在阅读有关DI和IoC的内容,但所有示例都控制了所有代码,而不是引用第三方API并处理它。我已经没想完了。

有关如何实现这一目标的任何想法?

5 个答案:

答案 0 :(得分:2)

dynamic in C#允许您使用后期绑定。然后我会建议一些反思来实现对象,就像下面的“逻辑”(未经测试,需要完成)

Type t = System.Reflection.Assembly.GetExecutingAssembly().GetType("ExternalDefinitionCreationOptions");
dynamic defOptions = t.GetConstructor().Invoke();

请注意,动态 var 不同。您的代码使用 var 作为让编译器决定类型的方法...现在动态只会在运行时定义类型。

答案 1 :(得分:2)

使用Augusto的基本代码(upvoted)以及对Reflection的更多研究我能够编写这个解决方案:

var assemblies = System.Reflection.Assembly.GetExecutingAssembly().GetReferencedAssemblies();
var assemblyName = assemblies.First(a => a.Name == "RevitAPI");
Assembly revitAssembly = Assembly.Load(assemblyName);

Type t = revitAssembly.GetType("Autodesk.Revit.DB.ExternalDefinitionCreationOptions"); // For Revit2016
if (t == null) t = revitAssembly.GetType("Autodesk.Revit.DB.ExternalDefinitonCreationOptions"); // For Revit2015

var types = new Type[1] { t };
var constructor = t.GetConstructors()[0];
dynamic defOptions = constructor.Invoke(new object[] { item.Name, parameterType });

答案 2 :(得分:1)

为什么不使用条件编译?

#if REVIT2015
   var defOptions = new ExternalDefinitonCreationOptions(name, parameterType);
#else
   var defOptions = new ExternalDefinitionCreationOptions(name, parameterType);
#endif

您必须在Revit 2015项目中定义REVIT2015条件编译符号(项目选项,构建选项卡)。

当然,这只有在你有两个独立的VS项目时才有效,它们包含一个源项目和一个项目,其中文件链接到源项目中的文件。

答案 3 :(得分:0)

我完全同意上面的maxence'方法。

我还建议将所有条件编译放入一个单一的兼容性模块中,并将其功能导出为方法或属性,例如:通过定义这样的方法:

ExternalDefinitionCreationOptions
  NewExternalDefinitionCreationOptions(
    string name,
    ParameterType parameterType )
{
  #if REVIT2015
    return new ExternalDefinitonCreationOptions(name, parameterType);
  #else // if not REVIT2015
    return new ExternalDefinitionCreationOptions( name, parameterType );
  #endif // REVIT2015
}

我在这里实现了这个:

https://github.com/jeremytammik/the_building_coder_samples/blob/master/BuildingCoder/BuildingCoder/Util.cs#L1209-L1225

玩得开心!

欢呼声

杰里米

答案 4 :(得分:0)

更新了在同一加载项中处理Revit 2015和Revit 2016 API的答案。

你真的想这样做吗?

好吧,如果你坚持,请点击这里:

import numpy as  np

class List:
    @staticmethod
    def map(rects, anchor_rect, f, filter_f, i=0, results=[]):
        if i == len(rects):
            return results
        rs = rects[i]
        anc_r = anchor_rect[i]
        for r in rs:
            if filter_f(r, anc_r):
                results.append(f(r, anc_r))
        return List.map(rects, anchor_rect, f, filter_f, i+1, results)

def my_f(r, anc_r):
    return r[0] + anc_r[0]

def filter_f(r, anc_r):
    return not np.all(r == 0)

rects = np.array([[[1, 2, 3, 5], [0, 0, 0, 0], [6, 7, 8, 9]]], dtype='int')
anchor_rect = np.array([[7, 7, 7, 7]], dtype='int')

print 'First call:',  List.map(rects, anchor_rect, my_f, filter_f)
print 'Parameters not changed:\n', rects, '\n', anchor_rect
print 'Second call:', List.map(rects, anchor_rect, my_f, filter_f)

用法:

#region Compatibility fix for spelling error change
/// <summary>
/// Wrapper to fix a spelling error prior to Revit 2016.
/// </summary>
public class SpellingErrorCorrector
{
  static bool _in_revit_2015_or_earlier;
  static Type _external_definition_creation_options_type;

  public SpellingErrorCorrector( Application app )
  {
    _in_revit_2015_or_earlier = 0
      <= app.VersionNumber.CompareTo( "2015" );

    string s
      = _in_revit_2015_or_earlier
        ? "ExternalDefinitonCreationOptions"
        : "ExternalDefinitionCreationOptions";

    _external_definition_creation_options_type
      = System.Reflection.Assembly
        .GetExecutingAssembly().GetType( s );
  }

  object NewExternalDefinitionCreationOptions(
    string name,
    ParameterType parameterType )
  {
    object[] args = new object[] { 
      name, parameterType };

    return _external_definition_creation_options_type
      .GetConstructor( new Type[] { 
        _external_definition_creation_options_type } )
      .Invoke( args );
  }

  public Definition NewDefinition(
    Definitions definitions,
    string name,
    ParameterType parameterType )
  {
    //return definitions.Create( 
    //  NewExternalDefinitionCreationOptions() );

    object opt
      = NewExternalDefinitionCreationOptions(
        name,
        parameterType );

    return typeof( Definitions ).InvokeMember(
      "Create", BindingFlags.InvokeMethod, null,
      definitions, new object[] { opt } )
      as Definition;
  }
}
#endregion // Compatibility fix for spelling error change

未测试!

干杯,

杰里米