Pergunta

Background

I am using Linq to SQL and thus have a generated DBML file containing auto-generated classes. Part of the generation process creates partial methods for certain actions, and in my case the two methods I am interested in related to the Insert and Update of table records. These partial methods are generated per each Table created in the DBML designer, for example:

partial void InsertMyTable(MyTable instance);
partial void UpdateMyTable(MyTable instance);

Now part of the design of my application requires that these two partial methods are always implemented for every single table. (They are essentially used to add a timestamp to the record being inserted/updated).

Requirement

I have a unit test project, and although this may not be common practice I want to include a few tests that ensure certain things have been implemented properly. In this case I want to ensure that the developers have remembered to implement the partial methods mentioned above (I do NOT care about the actually implementation, only that they have been implemented).

Problem

What I need to do is use reflection to check if each partial method has been implemented, but I am having trouble working out how to determine that.

Attempted Efforts

So far I have managed to get a list of methods contained within the data context, and I am able to compare that with the methods expected for each table. The problem is that I can't find a way to determine if a given partial method actually has an implementation:

var methods = (typeof(MyDataContext)).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var method in methods) 
{
    Console.WriteLine(method.Name);
    //how to check if method is implemented, or just an unimplemented partial
}
Foi útil?

Solução

What you have already works. If the partial method doesn't have an implementation, then it does not exist at all. There is no "declaration stub" that you might find by reflection accidentally. Either the partial method has an implementation, or it is removed completely by the compiler.

So basically: if you can't find the method with GetMethod / GetMethods (with the appropriate BindingFlags, as per the question) - then it wasn't implemented.

Outras dicas

As an alternative idea (and one that is obvious at compile-time, and which isn't susceptible to problems with obfuscation):

// generated code
public partial class Whatever : ISomeInterface<MyTable>
{
    //...
}

//somewhere else
public interface ISomeInterface<T>
{
    void Insert(T instance);
    void Update(T instance);
}

Now the compiler won't let the user proceed without implementing this interface completely, presumably in a partial class:

partial class Whatever
{
    public void Insert(MyTable instance) {...}
    public void Update(MyTable instance) {...}
}

(note they can still use explicit interface implementation, but you should use that interface yourself when accessing the data; avoids even more reflection)

When I ran into the same problem I solved it as follows:

var Method = (typeof(Entities))
.GetMethods(System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.FirstOrDefault(x => x.Name == "SomeMethodShouldBeOnPartialClass");
if (Method != null) Method.Invoke(this,null);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top