Declaring Exports

本文详细介绍了通过MEF(Managed Extensibility Framework)进行导出声明的不同方式,包括在组件级别、通过属性及方法进行导出,并展示了如何声明继承导出及发现非公开组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Declaring Exports 声明导出

Composable Parts declare exports through the [System.ComponentModel.Composition.ExportAttribute] attribute. In MEF there are several different ways to declare exports including at the Part level, and through Properties and Methods.

Composable Part exports 可组合部分的导出的声明形式

A Composable Part level export is used when a Composable Part needs to export itself. In order for a Composable Part to export itself, simply decorate the Composable Part with a [System.ComponentModel.Composition.ExportAttribute] attribute as is shown in the code snippet below.

[Export]
public class SomeComposablePart {
  ...
}
<Export()>
Public Class SomeComposablePart
    ... 
End Class

Property exports 属性导出的声明形式

Parts can also export properties. Property exports are advantageous for several reasons.
  • They allow exporting sealed types such as the core CLR types, or other third party types.
  • They allow decoupling the export from how the export is created. For example exporting the existing HttpContext which the runtime creates for you.
  • They allow having a family of related exports in the same Composable Part, such as a DefaultSendersRegistry Composable Part that exports a default set of senders as properties.
For example you might have a Configuration class that exports an integer with a "Timeout" contract as in the example below.

  public class Configuration
  {
    [Export("Timeout")]
    public int Timeout
    {
      get { return int.Parse(ConfigurationManager.AppSettings["Timeout"]); }
    }
  }
  [Export]
  public class UsesTimeout
  {
    [Import("Timeout")]
    public int Timeout { get; set; }
  }
Public Class Configuration
    <Export("Timeout")>
    Public ReadOnly Property Timeout() As Integer
        Get
            Return Integer.Parse(ConfigurationManager.AppSettings("Timeout"))
        End Get
    End Property
End Class
<Export()>
Public Class UsesTimeout
    <Import("Timeout")>
    Public Property Timeout() As Integer
End Class

Method exports 方法导出的声明形式

A method export is where a Part exports one its methods. Methods are exported as delegates which are specified in the Export contract. Method exports have several benefits including the following.
  • They allow finer grained control as to what is exported. For example, a rules engine might import a set of pluggable method exports.
  • They shield the caller from any knowledge of the type.
  • They can be generated through light code gen, which you cannot do with the other exports.
Note: Method exports may have no more than 4 arguments due to a framework limitation.

In the example below, the MessageSender class exports its Send method as an Action<string> delegate. The Processor imports the same delegate.

  public class MessageSender
  {
    [Export(typeof(Action<string>))]
    public void Send(string message)
    {
      Console.WriteLine(message);
    }
  }

  [Export]
  public class Processor
  {
    [Import(typeof(Action<string>))]
    public Action<string> MessageSender { get; set; }

    public void Send()
    {
      MessageSender("Processed");
    }
  }

Public Class MessageSender
    <Export(GetType(Action(Of String)))> 
    Public Sub Send(ByVal message As String) 
        Console.WriteLine(message) 
    End Sub
End Class

<Export()>
Public Class Processor
    <Import(GetType(Action(Of String)))> 
    Public Property MessageSender() As Action(Of String) 

    Public Sub Send()
        MessageSender()("Processed")
    End Sub
End Class

You can also export and import methods by using a simple string contract. For example below the "Sender" contract is used.

  public class MessageSender
  {
    [Export("MessageSender")]
    public void Send(string message)
    {
      Console.WriteLine(message);
    }
  }

  [Export]
  public class Processor
  {
    [Import("MessageSender")]
    public Action<string> MessageSender { get; set; }

    public void Send()
    {
      MessageSender("Processed");
    }
  }
Public Class MessageSender
    <Export("MessageSender")>
    Public Sub Send(ByVal message As String) 
        Console.WriteLine(message) 
    End Sub
End Class

<Export()>
Public Class Processor
    <Import("MessageSender")>
    Public Property MessageSender() As Action(Of String) 

    Public Sub Send()
        MessageSender()("Processed")
    End Sub
End Class

Note: When doing method exports, you are required to either provide a type or a string contract name, and cannot leave it blank.

Inherited Exports

MEF supports the ability for a base class / interface to define exports which are automatically inherited by implementers. This is ideal for integration with legacy frameworks which want to take advantage of MEF for discovery but do not want to require modifying existing customer code. In order to provide this capability use the System.ComponentModel.Composition.InheritedExportAttribute. For example below ILogger has an InheritedExport. Logger implements ILogger thus it automatically exports ILogger.

[InheritedExport]
public interface ILogger {
  void Log(string message);
}

public class Logger : ILogger {
  public void Log(string message);
}
<InheritedExport()>
Public Interface ILogger
    Sub Log(ByVal message As String) 
End Interface

Public Class Logger
    Implements ILogger
    Public Sub Log(ByVal message As String) Implements ILogger.Log

    End Sub

End Class

Discovering non-public Composable Parts

MEF supports discovery of public and non-public Parts. You don't need to do anything to enable this behavior. Please note that in medium/partial trust environments (including Silverlight) non-public composition will not be supported.
uniapp打包微信小程序,在小程序IDE中报错:Error: file: common/assets.js --- PLACEHOLDER PACKAGE --- This @babel/plugin-proposal-private-property-in-object version is not meant to be imported. Something is importing @babel/plugin-proposal-private-property-in-object without declaring it in its dependencies (or devDependencies) in the package.json file. Add "@babel/plugin-proposal-private-property-in-object" to your devDependencies to work around this error. This will make this message go away. Error: file: common/assets.js --- PLACEHOLDER PACKAGE --- This @babel/plugin-proposal-private-property-in-object version is not meant to be imported. Something is importing @babel/plugin-proposal-private-property-in-object without declaring it in its dependencies (or devDependencies) in the package.json file. Add "@babel/plugin-proposal-private-property-in-object" to your devDependencies to work around this error. This will make this message go away. at enhance (/Users/mark/Library/Application Support/微信开发者工具/50a7d9210159a32f006158795f893857/WeappCode/package.nw/js/common/miniprogram-builder/modules/corecompiler/summer/plugins/enhance.js:1:1579) at doTransform (/Users/mark/Library/Application Support/微信开发者工具/50a7d9210159a32f006158795f893857/WeappCode/package.nw/js/common/miniprogram-builder/modules/corecompiler/summer/plugins/enhance.js:1:1827) at Object.runSummerPluginHook (/Users/mark/Library/Application Support/微信开发者工具/50a7d9210159a32f006158795f893857/WeappCode/package.nw/js/common/miniprogram-builder/modules/corecompiler/summer/worker.js:2:1239)(env: macOS,mp,1.06.2504010; lib: 3.8.10)
07-16
FAILED: CMakeFiles/gazebo_aruco_plugin.dir/src/gazebo_aruco_plugin.cpp.o /usr/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_ATOMIC_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_IOSTREAMS_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_REGEX_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_TEST_DYN_LINK -DBOOST_THREAD_DYN_LINK -DLIBBULLET_VERSION=3.05 -DLIBBULLET_VERSION_GT_282 -Dgazebo_aruco_plugin_EXPORTS -I/home/yxz/PX4_Firmware/Tools/simulation/gazebo-classic/sitl_gazebo-classic/include -I/home/yxz/PX4_Firmware/build/px4_sitl_default/build_gazebo-classic -I/usr/include/eigen3/eigen3 -I/usr/include/gazebo-11/gazebo/msgs -I/home/yxz/PX4_Firmware/build/px4_sitl_default/mavlink -I/home/yxz/PX4_Firmware/build/px4_sitl_default/mavlink/mavlink/v2.0 -I/home/yxz/PX4_Firmware/Tools/simulation/gazebo-classic/sitl_gazebo-classic/external/OpticalFlow/include -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/gazebo-11 -isystem /usr/include/bullet -isystem /usr/include/simbody -isystem /usr/include/sdformat-9.7 -isystem /usr/include/ignition/math6 -isystem /usr/include/OGRE -isystem /usr/include/OGRE/Terrain -isystem /usr/include/OGRE/Paging -isystem /usr/include/ignition/transport8 -isystem /usr/include/ignition/msgs5 -isystem /usr/include/ignition/common3 -isystem /usr/include/ignition/fuel_tools4 -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -isystem /usr/include/eigen3 -isystem /usr/local/include/opencv4 -isystem /usr/include/sdformat-9.7/sdf/.. -isystem /usr/include/ignition/cmake2 -isystem /usr/include/uuid -O2 -g -DNDEBUG -fPIC -Wno-deprecated-declarations -Wno-address-of-packed-member -I/usr/include/uuid -MD -MT CMakeFiles/gazebo_aruco_plugin.dir/src/gazebo_aruco_plugin.cpp.o -MF CMakeFiles/gazebo_aruco_plugin.dir/src/gazebo_aruco_plugin.cpp.o.d -o CMakeFiles/gazebo_aruco_plugin.dir/src/gazebo_aruco_plugin.cpp.o -c /home/yxz/PX4_Firmware/Tools/simulation/gazebo-classic/sitl_gazebo-classic/src/gazebo_aruco_plugin.cpp In file included from /home/yxz/PX4_Firmware/Tools/simulation/gazebo-classic/sitl_gazebo-classic/src/gazebo_aruco_plugin.cpp:31: /home/yxz/PX4_Firmware/Tools/simulation/gazebo-classic/sitl_gazebo-classic/include/gazebo_aruco_plugin.h:41: fatal error: opencv2/aruco.hpp: No such file or directory 41 | #include <opencv2/aruco.hpp> | compilation terminated. [72/142] Building CXX object CMakeFile...erface.dir/src/mavlink_interface.cpp.o In file included from /usr/include/boost/smart_ptr/detail/sp_thread_sleep.hpp:22, from /usr/include/boost/smart_ptr/detail/yield_k.hpp:23, from /usr/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp:14, from /usr/include/boost/smart_ptr/detail/spinlock.hpp:42, from /usr/include/boost/smart_ptr/detail/spinlock_pool.hpp:25, from /usr/include/boost/smart_ptr/shared_ptr.hpp:29, from /usr/include/boost/shared_ptr.hpp:17, from /usr/include/boost/date_time/time_clock.hpp:17, from /usr/include/boost/date_time/posix_time/posix_time_types.hpp:10, from /usr/include/boost/asio/time_traits.hpp:23, from /usr/include/boost/asio/detail/timer_queue_ptime.hpp:22, from /usr/include/boost/asio/detail/deadline_timer_service.hpp:29, from /usr/include/boost/asio/basic_deadline_timer.hpp:25, from /usr/include/boost/asio.hpp:25, from /home/yxz/PX4_Firmware/Tools/simulation/gazebo-classic/sitl_gazebo-classic/include/mavlink_interface.h:36, from /home/yxz/PX4_Firmware/Tools/simulation/gazebo-classic/sitl_gazebo-classic/src/mavlink_interface.cpp:1: /usr/include/boost/bind.hpp:36:1: note: ‘#pragma message: The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated. Please use <boost/bind/bind.hpp> + using namespace boost::placeholders, or define BOOST_BIND_GLOBAL_PLACEHOLDERS to retain the current behavior.’ 36 | BOOST_PRAGMA_MESSAGE( | ^~~~~~~~~~~~~~~~~~~~ [77/142] Building CXX object CMakeFile...src/gazebo_camera_manager_plugin.cpp.o ninja: build stopped: subcommand failed. [899/903] Linking CXX executable bin/px4 FAILED: external/Stamp/sitl_gazebo-classic/sitl_gazebo-classic-build /home/yxz/PX4_Firmware/build/px4_sitl_default/external/Stamp/sitl_gazebo-classic/sitl_gazebo-classic-build cd /home/yxz/PX4_Firmware/build/px4_sitl_default/build_gazebo-classic && /usr/bin/cmake --build /home/yxz/PX4_Firmware/build/px4_sitl_default/build_gazebo-classic -- -j 7 ninja: build stopped: subcommand failed. make: *** [Makefile:227: px4_sitl_default] Error 1
07-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值