views:

33

answers:

1

Basically I would like to do something like this at the top of my class (I know this doesn't work as it isn't a constant)....

[XmlStorage(IsSingleStorageFile = false, IsSubordinate = true, StorageLocation = "posts" + GetBlogId()]

Where GetBlogId() would be a static utility method.

I'm building an xml storage framework for a blogging engine I am writing (partly a learning excercise, partly as I want to give something back to the open source) and I thought that the tidiest way to determine the storage location would be to use custom attributes since I would be to use a datacontractserializer anyway.

My only problem at present is determining the location for subordinate type whose location would be determined by the id of their parent. e.g Post < Blog.

My storage path would be something like this...

posts\blogid\postid.xml

Where the blog id would be determined by parsing the url and returning the associated blog. This would allow me to host multiple blogs in one installation whilst keeping post storage files separate to reduce memory overheads when loading posts.

Is this a straight no or is there a better way for me to do what I am attempting?

Edit:

Following John answer I tried this....

 private static string GetSubordinatePath(Type type)
    {
        if (typeof(ISubordinate).IsAssignableFrom(type))
        {
            object instance = Activator.CreateInstance(type);
            return (instance as ISubordinate).ParentGuid.ToString();
        }
        else
        {
            // TODO: Localize this.
            throw new ArgumentException(
            String.Format(
            CultureInfo.CurrentCulture,
            "The specified type '{0}' does not impliment the ISubordinate interface. Please edit the source appropriately to enable storage.",
            type.GetType().Name));
        }
    }

Which would be called from the class reading the custom attribute.

This works nicely..

+1  A: 

It's a straight no for attributes... the values are constants baked into the metadata.

One option you could use would be to have some sort of templating built into whatever uses the attributes... so you could have a storage location of posts\{GetBlogId()} and call the method at execution time. It's not exactly elegant though... you might want to consider using an interface instead.

Jon Skeet
Thanks....That's what I thought for attributes... Could you elaborate on the interface idea? My system is interface driven anyway.
James South
@James: Well, if you have an interface, your type could implement that interface and return whatever it wanted dynamically.
Jon Skeet
@Jon: I've edited my question with an attempt at this..... nearly there I hope.
James South
@James: Not quite, because the type itself wouldn't implement ISubordinate - you need to create an *instance* of the type.
Jon Skeet
@Jon: Thanks for the help. I've marked your answer and updated my code. I really appreciate how you got me to work out the answer. It really helps improve my understanding.
James South