4 Replies - 339 Views - Last Post: 16 January 2020 - 07:23 PM Rate Topic: -----

#1 UG Cyber   User is offline

  • D.I.C Addict

Reputation: 38
  • View blog
  • Posts: 624
  • Joined: 24-July 08

System.Reflection not retrieving interface attributes

Posted 07 January 2020 - 01:38 PM

[SOLVED] I had a duplicate definition of the attribute from when I split the project. Resolved by removing the definition in the main application and re-compiled.

I have a system that allows for 3rd party development for plugins. In order for the 3rd party libs to work, they need to inherit the specified interfaces to "explain" the functionality of the lib.

To make this easier to configure on the application side, I created custom attributes and attached them to the interface methods that describe the Entity Type and type of event like Export, Import, Transact, etc. (my possibly failed attempt at 1 source of truth) The issue is System.Reflection is not returning the custom attribute from the interface method. I have confirmed the presence of the attribute in the debugger and watches, but someMethod.GetCustomAttribute<type>() is returning null. Here is the code

[edit] the line in particular is getting the attribute DynamixEventAttribute from interfaceMethod

ILeadExport interface
namespace DynamixShared.Interfaces
{
    public interface ILeadExport
    {
        [DynamixEvent("Lead", "Export")]
        OutputResultModel ExportLead(LeadModel LeadData);

        [DynamixEvent("LeadList", "Export")]
        OutputResultModel ExportLeadList(LeadListModel ListData);
    }
}



Method that searches for custom attribute
        public List<InstanceEntityActions> GetApplicationActions(string applicationName)
        {
            Type applicationType = FindApplication(applicationName);
            if (applicationType == null)
            {
                return null;
            }

            List<InstanceEntityActions> entityActions = new List<InstanceEntityActions>();

            //Get all supported interfaces inherited by assembly and iterate
            IEnumerable<Type> applicationInterfaces = applicationType.GetInterfaces().Where(opt => _SupportedInterfaces.Contains(opt.Name));

            foreach (Type appInterface in applicationInterfaces)
            {
                //Get methods from interface and iterate, retrieve method entity and function name from interface

                foreach (MethodInfo interfaceMethod in appInterface.GetMethods())
                {
                    //Entity            = interfaceMethod.GetCustomAttributes (DynamixEntity)
                    //Action            = _SupportedInterfaces[Key].Value
                    //Additional Fields = applicationType.GetMethods().FirstOrDefault(interfaceMethod.Name).GetCustomAttributes() (RequiresFieldAttribute)

                    DynamixEventAttribute methodEntityAttribute = interfaceMethod.GetCustomAttribute<DynamixEventAttribute>(); //This is returning null
                    if (methodEntityAttribute == null)
                    {
                        continue;
                    }

                    EntityActions newAction = new EntityActions()
                    {
                        Name = methodEntityAttribute.Action,
                        RequiredFields = new List<ActionRequiredFields>()
                    };

                    List<RequiresFieldAttribute> applicationMethodRequirements = applicationType.GetMethod(interfaceMethod.Name)
                                                                                                        .GetCustomAttributes<RequiresFieldAttribute>()
                                                                                                        .Where(opt => opt is RequiresFieldAttribute)
                                                                                                        .ToList();

                    foreach (RequiresFieldAttribute methodRequiredField in applicationMethodRequirements)
                    {
                        newAction.RequiredFields.Add(new ActionRequiredFields()
                        {
                            DisplayName = methodRequiredField.DisplayName,
                            FieldName = methodRequiredField.FieldName,
                            HTMLType = methodRequiredField.HTMLType,
                            MaxLength = methodRequiredField.MaxLength,
                            MinLength = methodRequiredField.MinLength,
                            SelectOptions = methodRequiredField.SelectOptions
                        });
                    }

                    //Assign to entity actions
                    InstanceEntityActions existingEntityEntry = entityActions.FirstOrDefault(opt => opt.EntityType == methodEntityAttribute.EntityType);
                    if (existingEntityEntry != null)
                    {
                        //existing action should not exist at this point
                        existingEntityEntry.Actions.Add(newAction);
                    }
                    else
                    {
                        entityActions.Add(new InstanceEntityActions()
                        {
                            EntityType = methodEntityAttribute.EntityType,
                            Actions = new List<EntityActions>() { newAction }
                        });
                    }
                }
            }

            return entityActions;
        }



I should note that I'm using dotnet core 2.2 and the interfaces along with the attributes are in a separate project that is referenced by both the 3rd party libs and primary application. I am not getting any IDE/compiler/Debugger errors, just a null value returned.

Any help would be great. Its one of those "It was working when i left this project, why not now" kind of things :P/>/>/>

This post has been edited by UG Cyber: 07 January 2020 - 02:20 PM


Is This A Good Question/Topic? 0
  • +

Replies To: System.Reflection not retrieving interface attributes

#2 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7244
  • View blog
  • Posts: 24,556
  • Joined: 05-May 12

Re: System.Reflection not retrieving interface attributes

Posted 07 January 2020 - 02:27 PM

This doesn't answer your question, but why not use industrial strength MEF instead of rolling your own extensibility/adding infrastructure?

Anyway, I'm still trying to wrap my head around the problem you are describing. The particularly puzzling part is your statement that it used to work.
Was This Post Helpful? 1
  • +
  • -

#3 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7244
  • View blog
  • Posts: 24,556
  • Joined: 05-May 12

Re: System.Reflection not retrieving interface attributes

Posted 07 January 2020 - 07:22 PM

Just staring at the code you presenting, nothing is jumping out at me. The only things that come to mind are:
Are the namespaces consistent between declaring assembling and consuming assembly?
Is there only a single copy of the code/assembly that declares the interfaces and attributes?
Is the assembly version consistent? (e.g. AssemblyVersion property is not set for auto increment for each build.)

My recommendation is go through source control and keep going back versions until you get something working again. Then start rolling forward to see what change broke things.
Was This Post Helpful? 1
  • +
  • -

#4 UG Cyber   User is offline

  • D.I.C Addict

Reputation: 38
  • View blog
  • Posts: 624
  • Joined: 24-July 08

Re: System.Reflection not retrieving interface attributes

Posted 15 January 2020 - 08:55 AM

View PostSkydiver, on 07 January 2020 - 02:27 PM, said:

This doesn't answer your question, but why not use industrial strength MEF instead of rolling your own extensibility/adding infrastructure?


honestly, lack of knowledge of its existence. I am interested though and will take a look =) Thank you for the pointer.

The issue was duplicate definitions.
The application and the models/interfaces was in the same project initially. I then split them into two projects and referenced the shared lib (included the models, interfaces, attributes, etc) and removed all of the models from the main application. I completely forgot to remove the attributes from the main project. So the main project was searching for attributes it defined while the libs were referencing the attributes defined in the shared lib, both with the same name and contents.
Was This Post Helpful? 1
  • +
  • -

#5 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7244
  • View blog
  • Posts: 24,556
  • Joined: 05-May 12

Re: System.Reflection not retrieving interface attributes

Posted 16 January 2020 - 07:23 PM

So there wasn't a single source of truth. Glad to to hear that you figured it out.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1