Using reflection to check if a partial method has been implemented - c#

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
}

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.

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);

Related

Dependency Injection resolve correct implementation for database export

I want to store multiple objects in the database. The type of objects are not fixed and can be dynamically added by loaded modules. At one part in my application I want to search for the correct implementation to invoke the method with the created object.
One example. I have 3 objects:
public class Employee : Person { }
public class Supervisor : Person { }
public abstract class Person { }
and there are implementations of IExporter registered at the DI container:
public interface IExporter<T> where T: Person
{
Task ExportAsync(T person);
}
public class EmployeeExporter : IExporter<Employee>
{
public Task ExportAsync(Employee exployee) => Task.CompletedTask; // TODO
}
public class SupervisorExporter : IExporter<Supervisor>
{
public Task ExportAsync(Supervisor supervisor) => Task.CompletedTask; // TODO
}
How would my person factory which returns a person would know which Exporter is the right one to choose for export?
var type = typeof(IExporter<>).MakeGenericType(person.GetType());
var exporter = (IExporter<Employee>)serviceProvider.GetRequiredService(type);
await exporter.ExportAsync(person);
Something like this but without explicitly specify the IExporter<Employee> cast.
Or do I something completely wrong?
I already mentioned Jimmy Bogard's article, so I won't repeat that. Besides the options mentioned by Jimmy, there's another option, which is to use C# dynamic. This looks like this:
var type = typeof(IExporter<>).MakeGenericType(person.GetType());
dynamic exporter = serviceProvider.GetRequiredService(type);
await exporter.ExportAsync((dynamic)person);
At runtime, the C# compiler goes look for a method called ExportAsync. This is about the most concise solution you can get. But be aware of the following downsides:
Refactoring: This is not refactoring safe. If you refactor the IExporter<T> interface, this code keeps compiling but fails at runtime. You should add a unit test for your factory to make sure it still works.
Public only: Using the dynamic keyword, you can only invoke public methods on public classes. Even if your IExporter<T> is defined as public, when the exporter implementation (or the outer-most decorator your decided to wrap it with) is internal, the invocation will fail. To me this seems like a quirk in the C# compiler, because IMO it should be able to call ExportAsync when its interface is public, but that's not how it works. So again, you might want to add some unit tests to make sure it works.
What it comes down to when using dynamic, is that you'll be adding more tests than with the approaches Jimmy suggests. His solutions have more code and need less testing. Dynamic needs no extra code, but more testing code.

In C# can I cast MyService<Child> to MyService<Base>?

BACKGROUND: We've an ASP.NET Core based web app using EF Core developed on top of DI & Generic Repository pattern. So, most of the things are done using interfaces. Now, we've reached master table maintenance module. We don't want to replicate the same service (backed by repository) class for all 10-20 master tables.
So, we've created a _ModelMasterBase class and derived all the master table classes from it. The CRUD for all master tables is the same. So, next we implemented things like MasterRepository<T>, MasterService<T> and their interfaces. Now everything has to use <T> where T is the type of the master table selected on the page to perform CRUD.
Initially, I expected that instance of IMasterService<_ModelMasterBase> can be converted to IMasterService<T>
- again where T could be any child class derived from _ModelMasterBase - But it seems impossible! I've tried operators, casting, and almost everything I could google! Also due to repository pattern everything has to be strongly typed.
Now, we already use the trick to convert child obj to base class obj as per SO Post -
DerivedClass B = new DerivedClass();
BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B));
I know its a bit dirty trick but sometimes its handy to maintain the tradeoff between design and complexity. We use it with precaution. I wish there was something similar in case I wanted to cast MyService<Base> to MyService<Child>
Or you can forget all this and guide me to have a single point CRUD service for all my master tables - replicating the same thing 10-20 times seems irrational. Sorry, I couldn't explain in depth as it'd stretch the post.
Here's a v.basic sample of my code structure and at the end you'll see what we're trying to achieve. Hope it helps.
SOLUTION :
Based on mkArtak's suggestion, I was able to crack it by using
'Covariance' concept (example). Here's my updated code
sample. Now there's a single controller and service layer for all master tables!
Short answer: in the IMasterService definition prefix T with 'out' keyword.
public interface IMasterService<out T>
{
// your existing methods' definitions here
}
It's called Covariance, which is described in MSDN.
Inheritance problems?
This sort of thing smells like you should prefer composition over inheritance. As you're stating you're able to serialize/deserialize your specialized class to your base class, isn't this more like a data transfer object by definition? I wouldn't put logic into these but instead introduce another service that uses the base class logic without inheritance (e.g. passing an instance into the constructor) - that might solve the issue in the first place.
Not a solution
As of your particular question: you might be able to use a contravariant type parameter if this isn't too restrictive (e.g. you can only use the type parameter in parameters not in return types) and you own the interfaces in question. But the compiler only allows me to assign the services the other way around - which makes sense. Maybe you find a solution for this in a covariant manner instead?
using System;
public class Program
{
internal interface IMasterService<in T> {
void DoSomething(T table);
}
internal class BaseClass {}
internal class DerivedClass : BaseClass {}
internal class SpezializedService : IMasterService<BaseClass> {
public void DoSomething(BaseClass table) {}
}
public static void Main()
{
// The compiler isn't happy about the other way around
IMasterService<DerivedClass> baseService = new SpezializedService();
}
}
Hope this helps.

Accessing a private method from another class

I have two repository classes (RepositoryFactory and BaseRepository) implementing different interfaces within the same project. The BaseRepository class has a private method that would be now needed also in the other class, with the same implementation.
Instead of duplicate the method in order to keep it private, I was thinking to a possible alternative, although so far I could not find a good solution since by definition a private method has scope only in its own class.
Using inheritance and change the method to "protected" would also not be an option, since the two classes are not linked semantically. I cannot use a public property giving back the result of the method since the return type is void.
You can use reflection. Here's an example:
MethodInfo privMethod = objInstance.GetType().GetMethod("PrivateMethodName", BindingFlags.NonPublic | BindingFlags.Instance);
privMethod.Invoke(objInstance, new object[] { methodParameters });
It's not possible to do what you want in C#. The closest you can have is internal, which makes the member visible to an entire assembly. It might also be possible to make the two classes private and nested inside another class, but this isn't always appropriate.
Mads Torgersen, who works on C#, has this to say about it:
I've seen a number of proposals trying to grapple with some notion of "class set accessibility." The complication of course is that, unlike existing accessibilities, there is not already a natural group (everyone, assembly, derived classes, single class) to tie it to, so even with another accessibility modifier you still also need syntax (or something) to define the group.
There are several ways to slice it. I haven't seen a proposal that is obviously right, but I think the problem is relevant, and I will take this up with the design team.
(source)
You can, but it looks awkward. This takes advantage of nested classes being able to access private stuff from the containing class. However, even if something is possible doesn't mean you should do it. If you just change the modifier to internal you get the same behavior and since the two classes are coupled together then it makes sense to ship them in the same assembly, so internal modifier is the correct answer.
public class BaseRepository
{
public sealed class RepositoryFactory
{
public static BaseRepository Create()
{
var repo = new BaseRepository();
repo.MethodRequiredByRepositoryFactory();
return repo;
}
}
private void MethodRequiredByRepositoryFactory() { }
}
Reference
Possible by using reflection
Create a console application in Visual Studio.
Add 2 namespaces
2.1. System
2.2. System.Reflection
Now create a class and inside that class create one method that will be private as follows:

How can tweaks to existing methods in an auto-generated C# partial class be persisted?

I am working with Visual Studio Coded UI Tests, and wish to persist tweaks to the generated code.
The code is generated as a partial class in UIMap.cs and UIMap.Designer.cs, and so I know one solution would be to create a method with a slightly different name, such as myMethod_persist in UIMap.cs and use this instead of myMethod in UIMap.Designer.cs, which will be overwritten every time the source is regenerated.
This however seems very messy, and so what I'd prefer, is to instead override myMethod in UIMap.cs. This way the interface is not complicated with lots of gumph, and I don't have to remember to change every instance of myMethod in calling code to myMethod_persist
Unfortunately when it comes to C# I'm a bit of a noob, and don't even know if this is possible.
Basically what I want is this:
[UIMap.Designer.cs]
partial class myClass
{
public override void myMethod( int a ){ somethingHorrible(int a); };
}
[UIMap.cs]
partial class myClass
{
public sealed override void myMethod( int a ){ somethingNice(int a); };
}
But I know that the sealed and override keywords are usually used with derived subclasses classes, not partial classes. Is this possible? If not then what would be my best alternatives?
There's only one class here - myClass. The partial keyword just allows the class definition to be split across multiple files.
You can use partial methods, but only if the original (generated) method uses the partial keyword. You cannot override a method on the same class.
See Partial Classes and Methods (C# Programming Guide).
If you have no control over the auto-generation itself (ie. a framework or 3rd party generator) your options are somewhat limited. The two approaches that come to mind are to modify the generated code--which as you noted is not practical for changes that are significant and perhaps accumulating over time--and/or to create a derived class and use that instead of using the auto-generated class directly (assuming you control the code which would be using them, which seems likely).
A derived class (inheriting the auto-generated class) would be able to use override or new in the method declarations you want to replace. However, there are a lot of caveats to this approach as well. You can only "override" a method that was delcared as virtual in the base class (or was itself an override of another underlying virtual base, etc). You can also replace a method with a "new" one in the derived class, but the other code in the base class will not know about your "new" version and will not call it (whereas they will call your "override" because they know the method to be virtual). There are also issues of accessiblity; your derived class won't have access to private members of the base class.
But for some set of things you want to do it could work. In some cases you might have to tweak the auto-generated code slightly such as adding the keyword "virtual" or changing "private" members to "protected" so that you can access them from your derived class.
Added: Of course, you can also add new members to the original generated class in your own permanent file for the same partial class, and this code would have access to the class's private members. That can be another way to give your derived class access to the private members, such as by creating a protected property to wrap access to a private member field. If you didn't need to make changes to existing methods you wouldn't necessarily need to create a derived class, but your example talked about wanting to "override" methods from the auto-generated code, so presumably they already exist there.
Also note that a Designer file--such as for a Form or UserControl--does not usally get completely overwritten, so cautious changes outside the core generated code (eg. not inside the "Windows Form Designer generated code" region) can be made (and are persisted). For example, it is sometimes necessary to add a call to your own custom clean-up method in the Dispose(...) method in the Designer file.

C# share code between classes

In Visual Studio 2008 using C#, what is the best way to share code across multiple classes and source files?
Inheritance is not the solution as the classes already have a meaningful hierarchy.
Is there some neat feature that's like a C include file that let's you insert code anywhere you want in another class?
EDIT:
ok, i guess we need a concrete example...
There are several hundred classes in the domain with a well thought out class heirarchy. Now, many of these classes need to print. There is a utility printer class that handles the printing. Let's say there are 3 different print methods that are dependent on the class that is being printed. The code that calls the print method (6 lines) is what I'm trying to avoid copying and pasting across all the different client class pages.
It'd be nice if people wouldn't assume they knew more about the domain that the op - especially when they specifically mention techniques that don't fit...
If you have functionality that you use frequently in classes that represent very different things, in my experience that should fall into just a few categories:
Utilities (e.g. string formatting, parsing, ...)
Cross-cutting concerns (logging, security enforcement, ...)
For utility-type functionality you should consider creating separate classes, and referencing the utility classes where needed in the business class.
public class Validator
{
public bool IsValidName(string name);
}
class Patient
{
private Validator validator = new Validator();
public string FirstName
{
set
{
if (validator.IsValidName(value)) ... else ...
}
}
}
For cross-cutting concerns such as logging or security, I suggest you investigate Aspect-Oriented Programming.
Regarding the PrintA vs. PrintB example discussed in other comments, it sounds like an excellent case for the Factory Pattern. You define an interface e.g. IPrint, classes PrintA and PrintB that both implement IPrint, and assign an instance of IPrint based on what the particular page needs.
// Simplified example to explain:
public interface IPrint
{
public void Print(string);
}
public class PrintA : IPrint
{
public void Print(string input)
{ ... format as desired for A ... }
}
public class PrintB : IPrint
{
public void Print(string input)
{ ... format as desired for B ... }
}
class MyPage
{
IPrint printer;
public class MyPage(bool usePrintA)
{
if (usePrintA) printer = new PrintA(); else printer = new PrintB();
}
public PrintThePage()
{
printer.Print(thePageText);
}
}
You can't just load in code that you'd like to have added into a class in C# via a preprocessor directive like you would in C.
You could, however, define an interface and declare extension methods for that interface. The interface could then be implemented by your classes, and you can call the extension methods on those classes. E.g.
public interface IShareFunctionality { }
public static class Extensions
{
public static bool DoSomething(this IShareFunctionality input)
{
return input == null;
}
}
public class MyClass : Object, IShareFunctionality
{
public void SomeMethod()
{
if(this.DoSomething())
throw new Exception("Impossible!");
}
}
This would allow you to reuse functionality, but you cannot access the private members of the class like you would be able to if you could, say, hash include a file.
We might need some more concrete examples of what you want to do though?
A C# utility class will work. It acts like a central registry for common code (or like the VB.NET Module construct) - it should contain code that's not specific to any class otherwise it should have been attached to the relevant class.
You don't want to start copying source code around if you don't have to because that would lead to code update problems considering the duplication.
As long as the source doesn't need to retain state, then use a static class with static method.
static public class MySharedMembers {
static public string ConvertToInvariantCase(string str) {
//...logic
}
// .... other members
}
If the classes are in the same namespace, there's no need for an include analog. Simply call the members of the class defined in the other function.
If they're not in the same namespace, add the namespace of the classes you want to use in the usings directives and it should work the same as above.
I'm confused by the question: it seems you need to work on your basic OO understanding.
Checkout extension methods: http://msdn.microsoft.com/en-us/library/bb383977.aspx
I don't know of a way to include portions of files but one thing we do frequently is to add an existing file and "link" it from its current location. For example, we have an assemblyInfo.cs file that every project refers to from a solution directory. We change it once and all the projects have the same info because they're referring to the same file.
Otherwise, suggestions about refactoring "common" routines in a common.dll are the best thing I've come up with in .Net.
I am not sure exactly what you mean by a "meaningful" structure already, but this sounds like a place where you could use base class implementation. Though not as "verbose" as C++ multiple inheritance, you might get some benefit out of using chained base class implementation to reuse common functions.
You can preserve class hierarchy, at least visually and override behavior as needed.
Pull out the repetitive code into services. The repetitive code is a clue that there might be some room for refactoring.
For example, create a "PrintingService" which contains the logic needed to print. You can then have the classes that need to print have a dependency on this service (either via the constructor or a parameter in a method which requires the service).
Another tip i have along these lines is to create interfaces for base functionality and then use the interfaces to code against. For example, i had bunch of report classes which the user could either fax, email, or print. Instead of creating methods for each, i created a service for each, had them implement an interface that had a single method of Output(). I could then pass each service to the same method depending on what kind of output the user wanted. When the customer wanted to use eFax instead of faxing through the modem, it was just a matter of writing a new service that implemented this same interface.
To be honest I can't think of anything like includes in Visual C#, nor why you would want that feature. That said, partial classes can do something like it sounds what you want, but using them maybe clashes against your "classes already have a meaningful hierarchy" requirement.
You have many options, TT, extension method, delegate, and lambda

Categories

Resources