Add-ins and TypeDescriptor

Last post 05-14-2008, 5:28 PM by Gary. 10 replies.
Sort Posts: Previous Next
  •  05-09-2008, 4:49 PM 1094

    Add-ins and TypeDescriptor

    Hello Guys,

    I have found an issue, which prevents me from using TypeDescriptor on objects coming from an add-in. The TypeDescriptor is creating internally cache of object type properties for speed. When I unload (shutdown) an add-in and load the same add-in again, the cache is not relevant anymore. It throws an exception "AppDomainUnloadedException". I have tried to reset the TypeDescriptor cache, but unfortunately the objects returned from add-in have limited methods like "IsAssignableFrom", throwing "NotSupportedException". Also the add-in object Assembly property shows it is NULL. Please advise how can I make the add-in objects play nice with TypeDescriptor framework.

    Regards,
    Ivan


    SSIS Tasks Components Scripts | http://www.cozyroc.com/
  •  05-10-2008, 12:16 AM 1095 in reply to 1094

    Re: Add-ins and TypeDescriptor

    Hi Ivan,

    I have to do some research and testing on this, but to help me better understand, can you provide a little bit of clarification?

    • How do you have this architected? For example, I'm guessing that perhaps you return an object (as System.Object?) to the host application and the host application tries to determine what this object really is via the TypeDescriptor? 
    • When you say you try to "reset" the TypeDescriptor cache, do you use the Refresh method? If so, are you callng Refresh on the add-in assembly or on the object?
    • At what point in the application do you try to Refresh - when the new add-in is loaded?
    • When exactly is the "AppDomainUnloadedException" thrown?
    • When you say that the add-in objects have limited methods, what do you mean?
    • When you say that these methods throw "NotSupportedException",  is the exception thrown when you tryi to call those methods on the object?
    • If so, how are you calling the methods on the object? (wondering how this works with the proxy layer)

    If you can think of any other pertinent information, please pass that along, too!

    Best regards,
    Rebecca

     

     

     

  •  05-10-2008, 1:03 AM 1096 in reply to 1095

    Re: Add-ins and TypeDescriptor

    Hi Rebecca,

    Please check the answers to your questions:

    1. I use TypeDescriptor to show add-in object in a PropertyGrid.

    2. Yes I do use the TypeDescriptor.Refresh method. I have tried to use it on the object type and assembly. The add-in object property Assembly is always null. When I try to use add-in object type, it throws NotSupportedException because the Refresh method tries to get Module property of the type and it fails. I haven't tried to refresh based on add-in assembly. How can I retrieve the add-in assembly?

    3. I have tried before and after. But it doesn't matter because the entities, which are needed for the refresh are not provided by the add-in object.

    4. It is too hard to know when the first "AppDomainUnloadedException" is thrown because the VS debugger is not stopping. I have tried to debug only managed code and then both managed + unmanaged and it is still not able to stop. I was able to determine that it fails for certain inside the TypeDescriptor, when it tries to return information about the add-in object type.

    5. By limited add-in object methods I mean no support for Module, Assembly properties. The IsAssignableFrom method is also not supported and it is used extensively inside the TypeDescriptor.

    6. Yes, the exception is thrown when I try to use one of the above properties or methods. There are other methods not supported, but these in particular are needed for TypeDescriptor.

    7. I didn't quite understand your last question. Many methods and properties of the add-in object work properly, but not all of them.

    Let me know if you need further information. Thank you very much.

    Regards,
    Ivan


    SSIS Tasks Components Scripts | http://www.cozyroc.com/
  •  05-12-2008, 11:53 PM 1097 in reply to 1096

    Re: Add-ins and TypeDescriptor

    Hi Ivan,

    Thanks for the information! I'm trying to replicate the problem and I have seen the "AppDomainUnloadedException" already.

    I have one more question about your application so that I can replicate it better...

    Are you returning a System.Object from your add-in and then trying to determine its type using the TypeDescriptor? So far, in my experiment, I define a class in the add-in and return a reference to an instance of this class as a System.Object. When I try to query the component name or the class name or the properties, I get a "Specified Method is not supported" exception, so I am either not doing what you're doing or I'm missing a piece. Any insight would be really helpful!

    Thank you!
    Rebecca

  •  05-13-2008, 10:52 AM 1099 in reply to 1097

    Re: Add-ins and TypeDescriptor

    Hi Rebecca,

    Yes I get System.Object to an object instance from add-in. I then use methods from TypeDescriptor based on <object>.GetType(). TypeDescriptor supports also object instances, but the addin object doesn't handle many calls from TypeDescriptor and starts to throw not supported exceptions. I was able to get better results when I use the addin object type instead. The problems start to appear when I shutdown the addin and then load the same addin again and use the static TypeDescriptor methods on the type.

    Regards,
    Ivan


    SSIS Tasks Components Scripts | http://www.cozyroc.com/
  •  05-13-2008, 2:49 PM 1102 in reply to 1099

    Re: Add-ins and TypeDescriptor

     >>The problems start to appear when I shutdown the addin and then load the same addin again

     

    Just to clarify:  Can you can successfully use static TypeDescriptor methods on the add-in instance the first time the add-in is loaded?

  •  05-13-2008, 5:42 PM 1103 in reply to 1102

    Re: Add-ins and TypeDescriptor

    Gary,

    Using TypeDescriptor on the add-in object instance is not working because there are methods needed, which are not supported and it throws an exception. But using the methods on the addin object instance type is fine before the addin shutdown and reload.

    Regards,
    Ivan


    SSIS Tasks Components Scripts | http://www.cozyroc.com/
  •  05-13-2008, 8:16 PM 1104 in reply to 1103

    Re: Add-ins and TypeDescriptor

    VSTA team responds: 

    No fix for this problem on the VSTA side. According to your description, you get an add-in side object, put its type in TypeDescriptor, unload the add-in, reload the add-in back, and put the add-in side object Type into TypeDescriptor again. At that point, TypeDescriptor will do an == in its cache. RemoteType.Equals will fail because the first Type added into TypeDescriptor is already gone. TypeDescriptor doesn’t provide a method to remove the cache (TypeDescriptor.Refresh only removes the cached properties, events, not the type.) It may be possible if you implement your own TypeDescriptorProvider that does not do caching, but it’s something outside of VSTA or MAF.

  •  05-14-2008, 10:01 AM 1105 in reply to 1104

    Re: Add-ins and TypeDescriptor

    Thank you for your help Gary. At least this discussion will be useful for other people with similar problems.

    SSIS Tasks Components Scripts | http://www.cozyroc.com/
  •  05-14-2008, 2:08 PM 1107 in reply to 1104

    Re: Add-ins and TypeDescriptor

    Gary,

    I'm trying to find workaround for the issue. I have just found that the PropertyInfo returned using the standard reflection throw AppDomainUnloadedException. This has nothing to do with the TypeDescriptor framework and it is related to VSTA/MAF. Here is the code I'm using:

    PropertyInfo[] propInfos = objType.GetProperties();
    bool isClass = propInfos[0].PropertyType.IsClass;


    where objType is a type of an addin object. When I try to retrieve the IsClass, it throws an exception. When I call PropertyType.GetCustomAttributes it throws exception as well.

    Please advise.

    Regards,
    Ivan


    SSIS Tasks Components Scripts | http://www.cozyroc.com/
  •  05-14-2008, 5:28 PM 1110 in reply to 1107

    Re: Add-ins and TypeDescriptor

    As to your latest symptoms -- using reflection, I suspect you are still reflecting the old type, which has been unloaded.

     

    I tried the following code and if you use the new Type of the newly loaded add-in, you won’t have exception.

     

                    IEntryPoint addIn = addInToken[0].Activate<IEntryPoint>(AddInSecurityLevel.FullTrust);

                    addIn.Initialize(this.serviceProvider);

                    addIn.InitializeDataBindings();

                    addIn.FinishInitialization();

     

                    IExtendedMultipleEntryPoint addinEx = addIn as IExtendedMultipleEntryPoint;

                    Collection<object> epObjects = addinEx.GetEntryPointObjects();

     

                    object addinObject = epObjects[0];

                    Type objType = addinObject.GetType();

                    PropertyInfo[] propInfos = objType.GetProperties();

                    bool isClass = propInfos[0].PropertyType.IsClass;

     

                    //@@PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(addinObject.GetType());

                    AddInController aic = AddInController.GetAddInController(addIn);

                    addIn.OnShutdown();

                    aic.Shutdown();

     

                    IEntryPoint addIn2 = addInToken[0].Activate<IEntryPoint>(AddInSecurityLevel.FullTrust);

                    addIn2.Initialize(this.serviceProvider);

                    addIn2.InitializeDataBindings();

                    addIn2.FinishInitialization();

                    IExtendedMultipleEntryPoint addinEx2 = addIn2 as IExtendedMultipleEntryPoint;

     

                    Collection<object> epObjects2 = addinEx2.GetEntryPointObjects();

     

                    object addinObject2 = epObjects2[0];

                    bool useNewType = true;

                    if (useNewType)

                    {

                        Type objType2 = addinObject2.GetType();

                        PropertyInfo[] propInfos2 = objType2.GetProperties();

                        bool isClass2 = propInfos2[0].PropertyType.IsClass;

                         object[] objs = propInfos2[0].PropertyType.GetCustomAttributes(false);

                    }

                    else

                    {

                        PropertyInfo[] propInfos2 = objType.GetProperties();

                        bool isClass2 = propInfos2[0].PropertyType.IsClass;

                    }

     

View as RSS news feed in XML