using System;
using System.Runtime.InteropServices;
namespace Vanara.InteropServices
{
/// Factory for creating objects.
public static class ComReleaserFactory
{
/// Factory method to create a using type inference.
/// The type of the object.
/// The object.
/// A instance.
public static ComReleaser Create(TObj obj) where TObj : class => new ComReleaser(obj);
}
///
/// A safe variable to hold an instance of a COM class that automatically releases the instance on disposal.
///
/// The type of the COM object.
///
public class ComReleaser : IDisposable where T : class
{
/// Initializes a new instance of the class.
/// The COM object instance.
/// obj
/// Argument value must be a COM object. - obj
public ComReleaser(T obj)
{
if (obj == null) throw new ArgumentNullException(nameof(obj));
if (!obj.GetType().IsCOMObject) throw new ArgumentException("Argument value must be a COM object.", nameof(obj));
Item = obj;
}
/// Initializes a new instance of the class.
/// The COM object instance.
/// obj
/// Argument value must be a COM object and expose .
public ComReleaser(object obj)
{
if (obj == null) throw new ArgumentNullException(nameof(obj));
if (!obj.GetType().IsCOMObject) throw new ArgumentException("Argument value must be a COM object.", nameof(obj));
Item = obj is T t ? t : throw new ArgumentException($"Object must expose the {typeof(T).Name} interface.");
}
/// Gets the COM object.
/// The COM object.
public T Item { get; private set; }
/// Performs an implicit conversion from to .
/// The COM object.
/// The result of the conversion.
public static explicit operator ComReleaser(T obj) => new ComReleaser(obj);
/// Performs an implicit conversion from to .
/// The instance.
/// The result of the conversion.
public static explicit operator T(ComReleaser co) => co.Item;
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
{
Item = null;
}
}
}