Question

I am writing a small program. The interface I am writing to control each repository that is made defines a method of Save(IPublicObject). I am using LINQ for the SQL Version of the repository CRUD. My question is this. I would like to have only the one method which accepts the interface type. I want to think how I can best locate the Save action for the inherited type I then pass in.

In the book I am reading Patterns of Enterprise Application Architecture. I am leaning on the Inheritance Maping. So I create a derived object of

public class ConcretePublicObjectOne : IPublicObject{}

I want to then pass this into the Save Function of the respository. It is at this point where I am trying to think how best to say, ok we need to use "WHAT?" Save Method etc...

Should I use a registry, configuration setting mapping the types?

Was it helpful?

Solution

For LINQ-to-SQL, the data-context already does a lot of the mapping for you. As such, I think generics might be the best way to achieve a save while still having some consideration of your interface (although I'm not quite sure what the interface is giving you in this scenario...).

You can access the generic aspect of the data-context via GetTable<T>():

    static void Save<T>(T item)
        where T : class, IPublicObject
    {
        using (DataContext ctx = GetDataContext())
        {
            Table<T> table = ctx.GetTable<T>();
            // for insert...
            table.InsertOnSubmit(item);
            // for update...
            table.Attach(item, true);
            // for delete...
            table.DeleteOnSubmit(item);

            ctx.SubmitChanges();

        }
    }

Note that type-inference should mean that you don't need to specify the T when saving:

    Foo foo = new Foo();
    Save(foo); // <Foo> is inferred

Is that any use?

OTHER TIPS

What you wish to do is to have a:

Repository.Save(publicObject)

and the repository to call a method from publicObject?

If this is the requirement then you can define the Save method in repository as:

public class Repository {
    public void Save(IPublicObject publicObject) {
        publicObject.Save();
    }
}

where IPublicObject is defined as:

public interface IPublicObject {
    void Save();
}

But with this approach you will have to define a save method for each entity (like ConcretePublicObjectOne in your example)

Marc Gravell:

Thanks for that. As I say though I think using your example I would have to keep to the models that I get from the datacontext which kind of binds me to LINQ.

What you have done though is exactly the kind of thing I am looking for. It finds the type based on the object, and then knows which action to commit. Using your example, could I use anonymous types to apply a transformation to my models to work with that linq code. I have different storeage mdeiums you see which I need the models to wotk with across the board. The models are kind of self contain and know nothing about anything out side of them lol.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top