.NET으로 COM+ 객체를 만드는 예제.
.NET으로 COM+객체를 만들때는 먼저 Project Property에 Comvisible(true)로 설정이 되어 있어야지 된다. 그리고 assembly:Guid 속성에 component guid를 등록시켜야지만 com 객체를 만드는 가장 기초적인 설정이 끝이 난다. 이와같은 설정을 하면 작성된 dll이나 exe를 com+ 객체로 등록할 수 있다.
그러나, dll을 등록한다고해서 library안의 class들이 모두 com객체로 사용할 수 있는 것이 아니다. dll은 여러개의 com객체를 담을 수 있는 상자이고, 그 상자안에 채워야지 될 com객체들은 각각 작성되어야지 된다. com을 이용하는 것은 com 객체 뿐 아니라, com 객체를 구성하고 있는 interface역시 사용할 수 있어야지 되기 때문에, com으로 외부에서 노출될 모든 interface와 class들은 Guid Class Property를 갖고, 각 Guid 값을 가져야지 된다.
com으로 사용되기 위해서, class와 interface가 가져야지 될 속성은 각각 다른데, interface는 ComInterfaceType Property와 Guid를 가져야지 되며, class는 Com으로 제공될 ComSourceInterfaces, ClassInterface, Transaction, Guid, Com 객체 사용에서 Pool과 CreateTimeOut을 제한하는 ObjectPooling attribute를 가져야지 된다.
com interface 구현 예제
com class 구현 예제
.NET으로 COM+객체를 만들때는 먼저 Project Property에 Comvisible(true)로 설정이 되어 있어야지 된다. 그리고 assembly:Guid 속성에 component guid를 등록시켜야지만 com 객체를 만드는 가장 기초적인 설정이 끝이 난다. 이와같은 설정을 하면 작성된 dll이나 exe를 com+ 객체로 등록할 수 있다.
// Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(true)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("3308202e-a355-4c3b-805d-b527d1ef5fa3")]
그러나, dll을 등록한다고해서 library안의 class들이 모두 com객체로 사용할 수 있는 것이 아니다. dll은 여러개의 com객체를 담을 수 있는 상자이고, 그 상자안에 채워야지 될 com객체들은 각각 작성되어야지 된다. com을 이용하는 것은 com 객체 뿐 아니라, com 객체를 구성하고 있는 interface역시 사용할 수 있어야지 되기 때문에, com으로 외부에서 노출될 모든 interface와 class들은 Guid Class Property를 갖고, 각 Guid 값을 가져야지 된다.
com으로 사용되기 위해서, class와 interface가 가져야지 될 속성은 각각 다른데, interface는 ComInterfaceType Property와 Guid를 가져야지 되며, class는 Com으로 제공될 ComSourceInterfaces, ClassInterface, Transaction, Guid, Com 객체 사용에서 Pool과 CreateTimeOut을 제한하는 ObjectPooling attribute를 가져야지 된다.
com interface 구현 예제
#region Interfaces [Description("ICSSimpleObject description")] [Guid("2A59630E-4232-4582-AE47-706E2B648579")] // The public interface describing the COM interface of the coclass public interface ICSSimpleObject { #region Properties float FloatProperty { get; set; } #endregion #region Methods [Description("HelloWorld description")] string HelloWorld(); void GetProcessThreadID(out uint processId, out uint threadId); [Description("DoTransaction description")] void DoTransaction(); #endregion } [Guid("A06C000A-7A85-42dc-BA6D-BE736B6EB97A")] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] // The public interface describing the events the coclass can sink public interface ICSSimpleObjectEvents { #region Events [DispId(1)] void FloatPropertyChanging(float NewValue, ref bool Cancel); #endregion } #endregion
com class 구현 예제
// The ObjectPooling attribute is used to configure the component's object // pooling. It can enable or disables object pooling and set the min. or // max. pool size and object creation timeout. [ObjectPooling(MinPoolSize=2, MaxPoolSize=10, CreationTimeout=20)] // Creates the component with a new transaction, regardless of the state // of the current context. [Transaction(TransactionOption.Required)] [ClassInterface(ClassInterfaceType.None)] [ComSourceInterfaces(typeof(ICSSimpleObjectEvents))] [Guid("14EAD156-F55E-4d9b-A3C5-658D4BB56D30")] public class CSSimpleObject : ServicedComponent, ICSSimpleObject { #region Properties ////// The private members don't make it into the type-library and are /// hidden from the COM clients. /// private float fField = 0; ////// A public property with both get and set accessor methods. /// public float FloatProperty { get { return this.fField; } set { bool cancel = false; // Raise the event FloatPropertyChanging if (null != FloatPropertyChanging) FloatPropertyChanging(value, ref cancel); if (!cancel) this.fField = value; } } #endregion #region Methods ////// A public method that returns a string "HelloWorld". /// ///"HelloWorld" public string HelloWorld() { return "HelloWorld"; } ////// A public method with two outputs: the current process Id and the /// current thread Id. /// /// [out] The current process Id /// [out] The current thread Id public void GetProcessThreadID(out uint processId, out uint threadId) { processId = NativeMethod.GetCurrentProcessId(); threadId = NativeMethod.GetCurrentThreadId(); } public void DoTransaction() { try { // Operate on the resource managers like DBMS // ... ContextUtil.SetComplete(); // Commit } catch (Exception ex) { ContextUtil.SetAbort(); // Rollback throw ex; } } #endregion #region Events [ComVisible(false)] public delegate void FloatPropertyChangingEventHandler(float NewValue, ref bool Cancel); ////// A public event that is fired before new value is set to the /// FloatProperty property. The Cancel parameter allows the client /// to cancel the change of FloatProperty. /// public event FloatPropertyChangingEventHandler FloatPropertyChanging; #endregion }