因此,2016 API中更正了Revit 2015 API中的ExternalDefinitionCreationOptions had a spelling error。
我尝试使我的应用程序与当前版本+之前的版本尽可能兼容,但这次我甚至无法编译它,因为我只能引用两个API DLL中的一个,而{{1}在这个过程中起着重要作用。
代码如下:
\9
我正在阅读有关DI和IoC的内容,但所有示例都控制了所有代码,而不是引用第三方API并处理它。我已经没想完了。
有关如何实现这一目标的任何想法?
答案 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
}
我在这里实现了这个:
玩得开心!
欢呼声
杰里米
答案 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
未测试!
干杯,
杰里米