Search code examples
c#mef

Adding list into system attribute


I have created custom attribute that is part of MEF where I would like to define list of ids that are relevant to the class so I can query on them.

Also the class has to contain definition within itself, this is important that is why i thought about using:

[SignalSystemData("ServiceIds", new List<int>(){1})]

How shall I proceed?

My implementation of search is as follows:

        var c = new Class1();
        var v = c.EditorSystemList;

        foreach (var lazy in v.Where(x=>x.Metadata.LongName=="ServiceIds"))
        {
            if (lazy.Metadata.ServiceId.Contains(serviceIdToCall))
            {
                var v2 = lazy.Value;
                // v2 is the instance of MyEditorSystem
                Console.WriteLine(serviceIdToCall.ToString() + " found");

            }else
            {
                Console.WriteLine(serviceIdToCall.ToString() + " not found");
            }
        }

My Export class with definition should look like this:

[Export(typeof(IEditorSystem))]
[SignalSystemData("ServiceIds", new List<int>{1})]
public class MyEditorSystem1 : IEditorSystem
{
    void test()
    {
        Console.WriteLine("ServiceID : 1");
    }
}


public interface IEditorSystem
{
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class SignalSystemDataAttribute : ExportAttribute
{
    public SignalSystemDataAttribute(string longName, List<int> serviceId)
        : base(typeof (IEditorSystem))
    {
        LongName = longName;
        ServiceId = serviceId;
    }

    public string LongName { get; set; }
    public List<int> ServiceId { get; set; }

}

public interface IEditorSystemMetadata
{
    string LongName { get; }
    List<int> ServiceId { get; }
}

Solution

  • To get around the compile time constant issue, you have the following choices:

    • Use a specially formatted string (i.e. a comma separated list of integers, as you already suggested).
    • Use a number of overloads, each with a different number of arguments for the IDs. This will get messy if you have too many IDs to be passed.
    • Use params int[] ids as the last argument to your constructor. This will work, but is not CLS compliant - if that matters for you.
    • Most easily use an array int [] argument.

    Of course you could also use a combination of the above. Having a couple of overloads with say 1 to 5 ID arguments and providing a string argument or params int[] argument for those (hopefully) corner cases, where the overload arguments are not sufficient.

    Update: Just found this question/answer. Might not be duplicate as such, but deals with the same issue (mostly).