none
COMException attempting to invent a fluent API RRS feed

  • Question

  • Bear in mind, COM Interop is a little new to me. I am trying to come up with a fluent way to adapt between C# POCO objects and Interop classes. Seems like this isn't as possibly as I was thinking it should be.

    Any ideas where to begin with something like this? Is fluent even possible with COM Interop? Or I must take a more procedural approach? I hazard to speculate, it's entirely possible that I just can send COM objects across assembly boundaries in any kind of generic fashion.

    I have the COM Interop stuff in other assemblies than from where I am fluently originating the calls. Here's the basic code I've got going on. GetCells, SetValue, are also extension methods.

    entry.AdaptTo(row)
        .AdaptClass(c => c.Text,
                    (o, x) => o.GetCells(i, Columns.Text).SetValue(r => r.Value = x))
        .AdaptClass(c => c.TranslatedText,
                    (o, x) => o.GetCells(i, Columns.TranslatedText).SetValue(r => r.Value = x))
        .AdaptClass(c => c.Description,
                    (o, x) => o.GetCells(i, Columns.Description).SetValue(r => r.Value = x));
    
    
    public static FluentInteropClassAdapter<TClass, TInterop> AdaptTo<TClass, TInterop>(
        this TClass instance, ComWrapper<TInterop> obj)
    {
        return new FluentInteropClassAdapter<TClass, TInterop>(instance, obj);
    }
    
    public class FluentInteropClassAdapter<TClass, TInterop>
    {
        public TClass ClassInstance { get; private set; }
    
        protected ComWrapper<TInterop> InteropObject { get; private set; }
    
        internal FluentInteropClassAdapter(TClass instance, ComWrapper<TInterop> obj)
        {
            this.AcceptInteropObj(obj);
            this.ClassInstance = instance;
        }
    
        private void AcceptInteropObj(ComWrapper<TInterop> obj)
        {
            typeof(TInterop).VerifyComTypeInfo();
            this.InteropObject = obj;
        }
    
        public FluentInteropClassAdapter<TClass, TInterop> AdaptClass<T>(
            Func<TClass, T> getter, Action<ComWrapper<TInterop>, T> setter)
        {
            var value = getter(this.ClassInstance);
            setter(this.InteropObject, value);
            return this;
        }
    }
    
    System.Runtime.InteropServices.COMException occurred

      HResult=-2146827284
      Message=Exception from HRESULT: 0x800A03EC
      Source=""
      ErrorCode=-2146827284
      StackTrace:
           at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
           at Microsoft.Office.Interop.Excel.Range.get__Default(Object RowIndex, Object ColumnIndex)
           at DChem.Interop.Excel.ExcelExtensionMethods.GetCells(Range obj, Nullable`1 colIndex, Nullable`1 rowIndex) in c:\Source\Test\TestWinForms\DChem.Interop.Excel\ExtensionMethods.cs:line 132
      InnerException:

    Wednesday, December 26, 2012 8:16 PM

Answers

  • AH! Problem solved. Actually, was a bug in the GetCells code itself. That hadn't been exposed before because I had a ComWrapper<T> version and a T version for Range.

    Range r;
    r[0, 0]; //Error!
    r.Cells[0, 0] //Good!


    • Marked as answer by mwpowellhtx Wednesday, December 26, 2012 8:54 PM
    Wednesday, December 26, 2012 8:54 PM

All replies

  • Little more digging:

    exception-from-hresult-0x800a03ec-error post seems to suggest that it's an error of Excel saying it's "busy".

    From a couple other articles, also concerning calling into the COM Interop model from another thread. That's not the case, I can assure you.  I am calling in from one thread, although delegates are crossing assembly boundaries (?).

    I've read in another post that I may need to "invoke" into the COM Interop model to get at the features I need getting at? Currently in my Excel Interop layer, I've got fluent calls that simply access the COM interfaced properties, no invokes of any sort going on.

    Not real certain what exactly is going on, could use a little instruction.

    Thanks!

    Wednesday, December 26, 2012 8:40 PM
  • And just my own speculation now... As long as I was approaching the problem more "procedurally" using the vanilla (non fluent) GetCells and SetValues and such, that would work just fine. So, in my speculation, I wonder if it has to do with so many in the way anonymous delegates crossing assembly boundaries, or possibly some sort of other COM Interop reference counting thing. Again, don't know: I'm speculating. Any expert opinions?
    Wednesday, December 26, 2012 8:44 PM
  • AH! Problem solved. Actually, was a bug in the GetCells code itself. That hadn't been exposed before because I had a ComWrapper<T> version and a T version for Range.

    Range r;
    r[0, 0]; //Error!
    r.Cells[0, 0] //Good!


    • Marked as answer by mwpowellhtx Wednesday, December 26, 2012 8:54 PM
    Wednesday, December 26, 2012 8:54 PM
  • Hi,

    I'm glad to hear your issue has been solved. Your solution might be helpful for other community members.

    Thank you for sharing.

    Best regards,


    Quist Zhang [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, December 27, 2012 7:47 AM
    Moderator