Creating a Generic Save() Method for Models - c#

I have a fairly simple system, and for the purposes of this question there are essentially three parts: Models, Repositories, Application Code.
At the core are the models. Let's use a simple contrived example:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In that same project is a generic repository interface. At its simplest:
public interface IRepository<T>
{
T Save(T model);
}
Implementations of that interface are in a separate project and injected with StructureMap. For simplicity:
public class PersonRepository : IRepository<Person>
{
public Person Save(Person model)
{
throw new NotImplementedException("I got to the save method!");
// In the repository methods I would interact with the database, or
// potentially with some other service for data persistence. For
// now I'm just using LINQ to SQL to a single database, but in the
// future there will be more databases, external services, etc. all
// abstracted behind here.
}
}
So, in application code, if I wanted to save a model I would do this:
var rep = IoCFactory.Current.Container.GetInstance<IRepository<Person>>();
myPerson = rep.Save(myPerson);
Simple enough, but it feels like it could be automated a lot. That pattern holds throughout the application code, so what I'm looking to do is create a single generic Save() on all models which would just be a shorthand call to the above application code. That way one would need only call:
myPerson.Save();
But I can't seem to figure out a way to do it. Maybe it's deceptively simple and I'm just not looking at it from the correct angle. At first I tried creating an empty ISaveableModel<T> interface and intended to have each "save-able" model implement it, then for the single generic Save() method I would have an extension on the interface:
public static void Save<T>(this ISaveableModel<T> model)
{
var rep = IoCFactory.Current.Container.GetInstance<IRepository<T>>();
model = rep.Save(model);
}
But it tells me that rep.Save(model) has invalid arguments. It seems that it's not wiring up the type inference as I'd hoped it would. I tried a similar approach with a BaseModel<T> class from which models would inherit:
public class BaseModel<T>
{
public void Save()
{
this = IoCFactory.Current.Container.GetInstance<IRepository<T>>().Save(this);
}
}
But the compiler error is the same. Is there a way to achieve what I'm trying to achieve? I'm very flexible on the design, so if I'm going about something all wrong on an architectural level then I have room to step back and change the big picture.

Would a generic extension method solve it?
public static T Save<T>(this T current)
{
var rep = IoCFactory.Current.Container.GetInstance<IRepository<T>>();
rep.Save(current);
}
You can then constrain it to your ISaveableModel<T> interface. Return type above not implemented, but you can put it to a boolean or status flag, whatever.

In both approaches, the parameter to the Save() function is not of type T. In the first one, it is ISaveableModel<T>, and in the second, it is BaseModel<T>. Since the repository is a generic based on T, Save method will expect a variable of type T. You can add a simple cast to T before you call Save to fix it.
Alternatively, your IRepostory<T> can be changed to
public interface IRepository<T>
{
T Save(ISaveableModel<T> model);
}
which makes more sense.

Related

Injecting parents into composite constructors with Unity C#

I am trying to get IoC working with Unity in C# with the idea of a passing a wrapper/composite class into the children.
The top level class that composes multiple classes provides some common functionality that the composed classes require access to.
To illustrate:
// The top composite class
public class Context : IContext {
public ISomething SomethingProcessor { get; }
public IAnother AnotherProcessor { get; }
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.AnotherProcessor = processor;
}
// A function that individual classes need access to, which itself calls one of the children.
public string GetCommonData() {
return this.AnotherProcessor.GetMyData();
}
}
public class Something : ISomething {
private _wrapper;
public Something(IContext context) {
this._wrapper = context;
}
// This class has no knowledge of IAnother, and requests data from the master/top class, which knows where to look for whatever.
public void Do() {
Console.WriteLine(_wrapper.GetCommonData());
}
}
public class Another : IAnother {
public string GetMyData() {
return "Foo";
}
}
If you didn't use IoC, it's easy, as the constructor for the Context class becomes:
public Context() {
this.SomethingProcessor = new Processor(this);
this.AnotherProcessor = new Another();
}
But when you're using IoC, the idea of "this" doesn't exist yet because it is yet to be constructed by the injector. Instead what you have a is a circular dependency.
container.RegisterType<ISomething, Something>();
container.RegisterType<IAnother, Another>();
container.RegisterType<IContext, Context>();
var cxt = container.Resolve<IContext>(); // StackOverflowException
The above example has been greatly simplified to illustrate the concept. I'm struggling to find the "best practice" way of dealing with this kind of structure to enable IOC.
Factory pattern is a way construct an object based on other dependencies or logical choices.
Factory Method: "Define an interface for creating an object, but let
the classes which implement the interface decide which class to
instantiate. The Factory method lets a class defer instantiation to
subclasses" (c) GoF.
Lots of construction.. hence the name Factory Pattern
A crude code sample that could be used with DI
public class ContextFactory : IContextFactory {
_anotherProcessor = anotherProcessor;
public ContextFactory(IAnotherProcessor anotherProcessor) {
//you can leverage DI here to get dependancies
}
public IContext Create(){
Context factoryCreatedContext = new Context();
factoryCreatedContext.SomethingProcessor = new SomethingProcessor(factoryCreatedContext )
factoryCreatedContext.AnotherProcessor = _anotherProcessor;
//You can even decide here to use other implementation based on some dependencies. Useful for things like feature flags.. etc.
return context;
}
}
You can get away with this, maybe? - but there is still the cyclic reference issue here and I would never commit this kind of code.
The problem here you need to concentrate on Inversion Of Control of that GetCommonData
Your SomethingProcessor should not rely on methods in another class. This is where In Inheritance could be used but Inheritance can become very complicated very quickly.
The best way forward is to Identify the ONE thing that is needed by both or many other places and break that out into a new Dependency. That is how you Invert Control.
TIP:
Don't overdo Interfaces- Use Interfaces where you think you will be working with Polymorphism, such as a collection of different objects that must promise you they have implemented a specific method/property. Otherwise you are over using Interfaces and increasing complexity. DI doesn't have to use Interfaces it can be a concrete implementation. Interfaces on Repositories are a good use since you can switch Databases out easily but Interfaces a factory like this is not really needed.
I don't know the name of this pattern, or even if it is a bad or good practice, but you can solve your problem of "double-binding" by creating a method to bind the "IContext", instead of doing it in the constructor.
For instance,
1) ISomething has a void BindContext(IContext context) method
2) You implement it as such :
class Something : ISomething
{
IContext _wrapper;
// ... nothing in constructor
public void BindContext(IContext context)
{
_wrapper = context;
}
}
3) Remove the IContext dependency injection in Something constructor.
And you call it from the context constructor :
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.SomethingProcessor.BindContext(this);
// same for IAnother
}
And you do the same for IAnother. You could even extract some common interface "IBindContext" to make things a beat more "DRY" (Don't Repeat yourself) and make IAnother and ISomething inherit from it.
Not tested, and again : not sure it's the best way to do such dependency design. I'll be glad if there is another answer which gives a state-of-the-art insight about this.

Generic DAL / BLL Classes

I'm currently building the Data Access Layer and Business Logic Layer classes for our new application, and I have a question (obviously). First, here are some details that may help:
Using Entity Framework 5 for Model classes and data access
Each "layer" is separated in different class libraries and namespaces (i.e App.Model, App.DAL, App.BLL)
Starting with the DAL - I decided to write a base class for all DAL classes to inherit.
public abstract class DALBase<T> : IDisposable
{
protected AppEntities context;
protected DbSet set;
public DALBase()
{
context = new OECCORPEntities();
set = context.Set(typeof(T));
}
protected virtual void Save()
{
context.SaveChanges();
}
public virtual void Add(T model)
{
set.Add(model);
Save();
}
public virtual T Get(int id)
{
return (T)set.Find(id);
}
public virtual List<T> GetAll()
{
return set.OfType<T>().ToList();
}
public virtual void Delete(int id)
{
T obj = Get(id);
set.Remove(obj);
Save();
}
public virtual void Update()
{
Save();
}
public void Dispose()
{
context.Dispose();
}
}
As you will see, the base class implements a generic type which should be the type of the model the DAL class is responsible for working with. Using the generic type, in the constructor it creates a DbSet using the type of the generic argument - which is used in the predefined CRUD-like virtual functions below (add, get, etc).
And then I got the idea - wait a minute... since it's generic, I really don't have to implement DAL classes for every single model. I can just write something like this:
public class GenericDAL<T> : DALBase<T>
{
public GenericDAL() : base() {}
}
... that I can use for any of the models. OK, so on to the Business Logic Layer. I created a base class for BLL as well:
public abstract class BLLBase<T>
{
protected GenericDAL<T> dal;
public BLLBase()
{
dal = new GenericDAL<T>();
}
public virtual void Add(T model)
{
dal.Add(model);
}
public virtual T Get(int id)
{
return dal.Get(id);
}
public virtual List<T> GetAll()
{
return dal.GetAll();
}
public virtual void Delete(int id)
{
dal.Delete(id);
}
public virtual void Update()
{
dal.Update();
}
}
... which uses the GenericDAL to do its work. So in a simular fashion, I just wrote a GenericBLL class that looks like this:
public class GenericBLL<T> : BLLBase<T>
{
public GenericBLL() : base() { }
}
And to test it, a simple console application:
class Program
{
static void Main(string[] args)
{
GenericBLL<ADMIN> bll = new GenericBLL<ADMIN>();
List<ADMIN> admins = bll.GetAll();
}
}
... where "ADMIN" is the model type. Works like a charm.
The idea behind this was to avoid having to write DAL / BLL classes for every single model, unless it needed extra functionality. Can someone tell me why I WOULDN'T want to do it this way? I think the generic DAL / BLL classes would get the job done and also save development time.
Thank you for your time.
Well, one drawback is that if you decide to add some business rules later on you would have to switch the type from GenericBLL[Whatever] to WhateverBLL.
An obvious solution to this is to create a class that inherits from GenericBLL[Whatever]. Like:
public class WhateverBLL : GenericBLL<Whatever>
and use this class instead.
Right now, your BLL isn't particularly adding value. Every call is simply a pass-through to another layer. Maybe it's the simplicity of your application (and thank your lucky stars that you are so lucky), or maybe you have what I would classify as the actual business logic living elsewhere.
Business logic to me is everything that is done up to the point of persisting data, everything that is done after retrieving data, and things like that. The decisions, the forks in the road, the actions that are taken. Actually saving and retrieving data is typical extremely trivial by comparison.
So as I look at your generic DAL base class, I think it's a fine start. I would probably extract an interface from it so I could replace it when testing. For now, your class that inherits the base isn't adding any value. Do not create layers and classes simply for the sake of it, be sure it adds value and makes your life easier in some way.
As I look at your generic BLL class, I think you probably have your real business logic tucked away in the codebehind on some form, or inside a class file in a console app. While it's certainly possible that there could be generically applicable functionality that only varies on the type, I don't think one class is where you want to be. My suggestion here is to reconsider what you think is your actual business logic. A simple pass-through layer to the DAL probably isn't it.

Populating collection via an interface/factory?

I am using a pattern where a concrete ViewModel implementing an interface is passed to a repository, which then populates the ViewModel object, but only using the interface. This makes for a little heavier repository, but has allowed the repository to be reused in different scenarios. For example, the concrete implementation could be a MVC ViewModel, or it could be asp.net Page that implements the interface, where the set accessor for each proeprty is actually putting the value in to the GUI, like a textbox for example. The implementation of the interface serves as the mapping and eliminates an extra step of copying. Having used AutoMapper extensively, and now being exposed to this pattern, I prefer this.
public interface IPerson
{
int Id{set};
string Name{set};
string Address{set};
}
public class PersonRepository
{
GetPerson(int id, IPerson person)
{
//query...
person.Id = result.Id;
person.Name = result.Name;
person.Address = result.Address;
}
}
//...controller action
PersonViewModel person = new PersonViewModel();
rep.GetPerson(5, person);
Here comes the tricky part though. Sometimes the ViewModel needs a collection of items, either for an Index page or for something like a drop down, or to display a nested set of child objects. The repository can't instantiate an interface, so we provide it was a factory. After fighting with covariance for awhile, I gave up on exposing any type of collection and ended up with a method that both creates and adds the collection item:
public interface IPerson
{
//...
IJobRole CreateAndAddJobRole();
}
public class PersonViewModel:IPerson
{
//collection not part of the interface
ICollection<JobRoles> JobRoles {get;set;} //= new List<JobRoles> in constructor
public CreateAndAddJobRole()
{
role = new JobRole();
JobRoles.Add(role);
return role;
}
}
public class PersonRepository
{
GetPerson(int id, IPerson person)
{
//...
foreach(var result...)
{
IJobRole role = person.CreateAndAddJobRole();
role.SomeProperty = //...
}
}
}
Obviously I'd probably have the repository that handles job roles actually be the one to populate the collection. I'd probably actual have more granular interfaces so that different repositories would be responsible for populating the data they deal with. The ViewModel would simply implement multiple interfaces. That to say, I realize there's room for improvement, but I am here specifically because I don't have any good ideas for dealing with the collection problem.
The one benefit of this design is there is no collection exposed which could be misused by the repository. There is never a guess about who is responsible for instantiating the collection itself, or who populates it, or if you had just a getter, the repository could get the collection and modify it in an invalid way. I think these would be rare occurrences because of the team would know the pattern, but it's always nice to not have pitfalls at all, instead of having pitfalls there that everyone has to remember to not step in.
As it is, it feels a little mucky.
How would you design/expose the ability for concrete types to be instantiated and added to collection, when the method doing so only has knowledge of the interfaces?
It sounds like your best bet is to make each interface generic, and pass in the types of the collections. For example:
public interface IPerson<TJob> where TJob : IJobRole
{
ICollection<TJob> JobRoles {get;set;}
void AddJobRole(TJob role);
}
public JobRole : IJobRole
{
}
public class PersonViewModel:IPerson<JobRoles>
{
//collection is now part of the interface
ICollection<JobRoles> JobRoles //= new List<JobRoles> in constructor
public void AddJobRole(JobRoles role)
{
JobRoles.Add(role);
}
}
public class PersonRepository
{
GetPerson(int id, IPerson<JobRoles> person)
{
//...
foreach(var result...)
{
person.AddJobRole(new JobRole {
SomeProperty = //...
SomeOther = //...
}
}
}
}
Of course, this assumes that you know which type of IPerson<> you want when you call GetPerson(). If you need it to handle any IPerson there, though, it becomes more problematic.

Constructor injection with non-dependency parameters

I have an interface ITradingApi like so:
public interface ITradingApi
{
IOrder CreateOrder(...);
IEnumerable<Symbol> GetAllSymbols();
// ...
}
This is meant to be a facade for the different APIs of the vendors of trading software.
My view model has a dependency on this trading API in its constructor:
public class MainViewModel
{
public MainViewModel(ITradingApi tradingApi) { /* ... */ }
// ...
}
I use Ninject as an IoC container, so I will create an instance of my view model like this:
var vm = kernel.Get<MainViewModel>();
Now, my problem:
The implementation of ITradingApi might need additional parameters to work.
Example:
One vendors API uses TCP/IP internally, so I need a hostname and a port.
Another vendor uses a COM object. Here I don't need any info.
A third vendor needs username and password of the account.
In the spirit of not allowing incomplete objects, I added these as parameters to the constructors of the concrete implementations.
Now, I am not sure, how this would work. Clearly, these additional parameters do not belong into the interface, because they are specific to each implementation.
On the other hand, these additional parameters need to be entered by the end-user and then passed to the implementation of ITradingApi, meaning that the user of ITradingApi needs intimate knowledge about the concrete implementation.
How to solve this dilemma?
UPDATE:
One approach could be to create an ITradingApiProvider that exposes a list of required parameters. The View could automatically create an input form for these parameters that is databound to the parameters in ITradingApiProvider. Now, when an ITradingApi instance is requested from the provider, it can make use of these parameters to create an instance of the concrete implementation. Clearly the implementation of ITradingApiProvider and ITradingApi are tightly coupled, but I think that is not a problem as long as each implementation of ITradingApi comes with a corresponding implementation of ITradingApiProvider.
Based on the information so far put forth here, I'd like to point out one or two things:
First of all, whether or not the concrete configuration values are supplied at composition time or truly first available at runtime as user input makes a huge difference. As long as they can be resolved at composition time things are easy because you can simply read the values from the environment and supply them to the appropriate constructors. So, for the rest of this answer I'm going to assume that things are much harder and you actually need to get those values from the user at runtime.
Instead of attempting to come up with a general-purpose configuration API I'd much rather model what's actually going on. In this case it sounds to me like we're collecting configuration values from the user, so why not model this explicitly?
Product Trader
Define an interface like this:
public interface ITradingApiTrader
{
ITradingApi Create(Type apiType);
}
Here, it's assumed that apiType can cast to ITradingApi, but this can't be enforced by the compiler. (The reason I'm calling this a 'Trader' is because this is a variation of the Product Trader pattern (PLoPD 3).)
How is this different than before?
Well, you can implement the Create method by showing a user interface for each type of ITradingApi. Each concrete user interface gathers the values required for its own concrete ITradingApi implementation and subsequently returns a correctly configured instance.
If you know the concrete types at compile time, other variations include these:
public interface ITradingApiTrader
{
ITradingApi CreateMT4TradingApi();
ITradingApi CreateFooTradingApi();
ITradingApi CreateBarTradingApi();
// etc.
}
Perhaps you can also do this (although I haven't tried to compile this):
public interface ITradingApiTrader
{
ITradingApi Create<T>() where T : ITradingApi;
}
Note also that you don't need to define the first ITradingApiTrader's Create method based on a Type - any identifier (such as an enum or string) might do instead.
Visitor
If the set of ITradingApi is (finite and) known at design time, the Visitor design pattern might also offer an alternative.
If you use a Visitor, you can make the Visit method show an appropriate user interface and then subsequently use the values collected from the user interface to create the appropriate ITradingApi instance.
Basically this is just a variation on the previous 'solution' where the Product Trader is implemented as a Visitor.
Is this what your after?
ninjectKernel.Get<MainViewModel>().WithConstructorArgument("tradingApi",
kernel.Get<ITaxCalculator>() .WithConstructorArgument("additionalParameter","someValue")));
Ok my two cents, I am not sure of anything you know. It is just to help and try...
We give a visitor to your api as construction of the interface:
public interface ITradingApi
{
Object CreateOrder();
IEnumerable<Object> GetAllSymbols();
}
public class TradingApi : ITradingApi
{
IvisitorAPI _VisitorAPI;
public TradingApi(IvisitorAPI visitorAPI)
{
_VisitorAPI = visitorAPI;
}
public Object CreateOrder()
{
var Order = new Object();
//bla bla bla
//here code relative to different visitor
_VisitorAPI.SaveOrder(Order);
return Order;
}
}
It is your visitor that knows how to handle some of the action, because depending on the visitor he will use your api in different ways to achieve the same action ( here SaveOrder).
public interface IvisitorAPI
{
bool SaveOrder(Object order);
}
public class visitorApiIP : IvisitorAPI
{
public string HostName { get; set; }
public int Port { get; set; }
public visitorApiIP(string hostname, int port)
{
HostName = hostname;
Port = port;
}
public bool SaveOrder(Object order)
{
//save the order using hostname and ip
//...
//....
return true;
}
}
Only the visitor has a knowledge of what he needs to achieve his version of the action.
Therefore it is not the APi that needs additionnal parameters, we are pushing the logic away in the visitor class.
This visitor class might be created only when ewe know who is the visitor therefore, surely at runtime
Hope it might give you some perspective. I do not know if the whole theory can be applied your exact situation.
My best anyway ;)
The solution is to use the approach as outlined in the update part of my question. ITradingApiProvider takes the role of an abstract factory and thus should be renamed to ITradingApiFactory. It would expose a list of needed parameters whose values can be set. This list in turn can be used by the View to automatically present the user with an input form to enter a value for each parameter, because only the user knows the values of for the parameters.
The call to Create would then use these parameters:
public interface ITradingApiFactory
{
ITradingApi Create();
IEnumerable<Parameter> Parameters { get; }
}
public class Parameter
{
public Parameter(Type type, string name, string description)
{ Type = type; Name = name; Description = description; }
public Type Type { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public object Value { get; set; }
}
public class MT4TradingApiFactory : ITradingApiFactory
{
Dictionary<string, Parameter> _parameters;
public MT4TradingApiFactory()
{ /* init _parameters */ }
public ITradingApi Create()
{
return new MT4TradingApi(_parameters["hostname"].ToString(),
(int)_parameters["port"]);
}
IEnumerable<Parameter> Parameters { get { return _parameters.Values; } }
}
More info can be found in this answer.
This can be advanced further to make it easier to use, by giving each Factory implementation the parameters as properties and change the Parameter class to work directly on these properties using expression trees. If someone is interested in this advanced factory design, please leave a comment.
I think there is nothing wrong with your provider approach. You have two concerns here:
An operational one: your ITradingAPI which defines a contract for operations you can perform.
A meta-data one: something which describes properties of an actual implementation (meta data might not be quiet right but can't think of a better name for it)
Now apparently you need something which can make the connection between the two and that is your ITradingAPIProvider. Seems reasonable straight forward and has good chance of that you will still understand your code when coming back to it after a year ot two ;)
How about trying something similar to the strategy pattern? Create a new interface called IConnectStrategy:
interface IConnectStrategy
{
void Connect();
}
Add the connectstrategy as an argument to the method void CreateOrder(IConnectStrategy connectStrategy) in ITradingApi and let each vendor create/specify their own method for connecting. E.g. for one vendor create:
public class TCPConnectStrategy : IConnectStrategy
{
public TCPConnectStrategy(string hostName, int port)
{
/* ... */
}
public void Connect()
{
/* ... tcp connect ... */
}
}
(Connect might not be the best name or even what you are actually doing, but please apply it to whatever works for your project.)
Edit after comments:
Create a strategy that only have contracts for each method that have vendor-specific parameters. Then add a method void SetVendorStrategy(IVendorStrategy vendorStrategy) (or a property) to the ITradingAPI-interface. Each implementation of the strategy has their own constructor with their own parameters, and each method (that require vendor specific parameters) in each implementation of the ITradingAPI-interface simply calls vendorStrategy.DoSomethingWithVendorSpecificData().

In a Generic Provider how to find and edit properties of T? (C#)

So, I'm making a generic provider for my repositories implementation which will be used by my BaseController (ASP.NET MVC 2) for low-level objects. These objects have common operations, such as Activate/Deactivate/Delete/Edit, so I'll always be working with the same property on each. The problem is, since I don't know what T is, I obviously don't have access to its properties.
So, my question is, can someone show me how to get the properties I need out of the objects. I've seen some people talking about Reflection, others Expression Trees, neither of which I know how to use.
I do have a generic repository which I believe uses Expression Trees (copied it from some website), but again, I don't know what I'm doing with it... If it helps, here's what I've got so far:
public class Provider<T> where T : class {
private readonly Repository<T> Repository = null;
public Provider(
Repository<T> Repository) {
this.Repository = Repository;
}
public void Activate(
int Id) {
T Entity = this.Repository.Select(Id);
// Need to get the property here, change it and move on...
this.Repository.Submit();
}
}
I'd appreciate any help on this.
If those classes have common operations, sounds like they should inherit from the same base or implement the same interface, correct? If so, use that interface/base as the constraint for T
public class Provider<T> where T : ICommonInterface
You will then have compile-time access to the shared members provided by the interface or base class.
You could make an action
public void Activate(int Id, Action<T> doSomething)
{
T Entity = this._repository.Select(Id);
// Need to get the property here, change it and move on...
doSomething(Entity);
_repository.Submit();
}
Then using the Action delegate (in this example via a lambda) the properties will be known when activate is called:
prov.Activate(5, x => x.Address = "fgfgf");
The best solution will be to give the objects a common base type, and constrain the type parameter T to be of that type. Then you'll have access to the methods or properties of the common base type at compile time:
public class Provider<T> where T : ICommon
{
...
}
or
public class Provider<T> where T : CommonBase
{
...
}
If that's not possible, then without a common base type the best you can do is reflect upon the objects to look for and invoke the property that you are interested in:
public void Activate(int Id)
{
T entity = this.Repository.Select(Id);
// Interrogate the type of the entity and get the property called "MyPropertyName"
PropertyInfo pi = entity.GetType().GetProperty("MyPropertyName");
// Invoke the property against the entity instance - this retrieves the
// value of the property.
var value = (YourType)(pi.GetValue(entity, null));
// Do somethign with the value...
this.Repository.Submit();
}
I should add that reflection is comparatively expensive and you also lose the compile time verification. But it's handy in cases like these.
You can get a MethodInfo object for working with methods by calling:
MethodInfo mi = entity.GetType().GetMethod("MyMethodName");

Categories

Resources