Dead.Rabit
Dead.Rabit

Reputation: 1975

Custom Enum Type

I have a Flag based enum, and while it doesn't currently exceed the bounds of 64 value (long), it potentially will.

I'm using the enum to describe which of our customers an MEF plugin/component is meant for. This will be our main mechanism for implementing customer customisations.

I'm fairly certain my bosses won't be too pleased with the idea that we can only serve 64 customers, but I cannot implement such a flexible system without an Enum.

Ideally, I'd like to write:

[Flags]
public enum Organisations : MyBinaryFormat
{
    // Customers
    CustomerA = 1 << 0,
    CustomerB = 1 << 1,
    CustomerC = 1 << 2,
    CustomerD = 1 << 3,

    // Special
    Any                 = CustomerA | CustomerB | CustomerC,
    HostedCustomers     = CustomerA | CustomerC,
}

This is a very convenient syntax for defining my metadata, unfortunately hacking types isn't really my forte so I've tried my best to research/experiment around the topic but haven't come to much:

I'd like to know definitively if constructing an enum on a custom type is possible

Upvotes: 0

Views: 6666

Answers (2)

Matthew Abbott
Matthew Abbott

Reputation: 61617

Would it not be better to express them as an array of unique strings (or numbers) that represent the customer Id?

E.g, you could define a metadata interface like:

public interface ICustomerValidityMetadata
{
    string[] ValidCustomers { get; }
}

Which you could roll into a metadata attribute:

[MetadataAttribute]
public class ExportForCustomerAttribute : ExportAttribute, ICustomerValidityMetadata
{
    public ExportForCustomerAttribute(Type type, params string[] customerIds)
        : base(type)
    {
        ValidCustomers = customerIds ?? new string[0];
    }
}

Which you could then apply as:

[ExportForCustomer(typeof(IModule), "CustomerA", "CustomerB")]
public class SomeModule : IModule { }

And you can then filter:

var modules = container.GetExports<IModule, ICustomerValidityMetadata>()
    .Where(l => l.Metadata.ValidCustomers.Contains("CustomerA");

But, to be honest, hard coding representations of changeable entities is a bad idea, you should really do a lookup dynamically, either from a database, or config, etc. That way you need only export some metadata representing the module Id, which you can then lookup against a specific customer to see if it is useable.

Hope that helps.

Upvotes: 1

ColinE
ColinE

Reputation: 70170

What is wrong with defining a CustomerList class which contains a list of CustomerIDs or even just List<int>? The .NET API has numerous List manipulation methods that will allow you to OR together lists of customer IDs just as you have done with your flags enum.

e.g.

List<int> hostedCustomers = new List<int>{1,4, 5};
List<int> newCustomers = new List<int>{6,4,7};
List<int> newHostedCustomers = hostedCustomers.Union(newCustomers).ToList();

Upvotes: 2

Related Questions