i want to use plugins to extend my c# wpf application. i've made a simple interface, then a plugin dll, then a test class to load the plugin. the plugin load properly and i can get a list of its properties.
the inteface:
public interface IStrat
{
string Name { get; }
void Init();
void Close(int dat);
}
the plugin:
public class Class1 : IStrat
{
public string info;
[Input("Info")]
public string Info
{
get
{
return info;
}
set
{
info = value;
}
}
public string Name
{
get { return "Test Strategy 1"; }
}
public void Init()
{
}
public void Close(int dat)
{
}
}
the test class:
class test
{
public void getPlugins()
{
Assembly myDll = Assembly.LoadFrom(Class1.dll);
var plugIn = myDll.GetTypes();
List<string> temp = new List<string>();
//gets the properties with "input" attribute, it returns the Info property fine
var props = item.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(Input)));
foreach (var prop in props)
{
temp.Add(prop.Name + " (" + prop.PropertyType.Name + ")");// returns Info (string)
}
stratFields.Add(item.Name, temp);// stratFields is a dictionary that keeps the name of the plugin as key and a list of properties names as value
}
public void create()
{
//create an instance of my plugin
Type t = plugIn[0];
var myPlugin = (IStrat)Activator.CreateInstance(t);
myPlugin.Init(); // this works, i can access the methods
myPlugin.Info = "test"; //this doesn't work
}
}
i want to access the "Info" property to get/set it for that specific instance. when i use the getproperties() method it finds it, so there must be a way to use it.
different plugins have different number and type of properties.
Since Info property is not part of the interface you have to use reflection (Set object property using reflection) or dynamic:
myPlugin.Init(); // this works because IStrat has Init method
dynamic plugin = myPlugin;
plugin.Info = "test"; // this works because `Info` is public property and
// dynamic will perform late (run-time) binding.
Better approach would be add all necessary methods to the interface.
Related
Just to clarify, I have this working using dynamic and MakeGenericType. But I cant help but think there is a better way to do this. What I am trying to do is create a "plug-in" loader, using Unity. I will just explain it as I post the code so you can get a sense for what I am doing.
First I'll just post the plug-in itself:
[RegisterAction("MyPlugin", typeof(bool), typeof(MyPlugin))]
public class MyPlugin: IStrategy<bool>
{
public IStrategyResult<bool> Execute(ISerializable info = null)
{
bool result;
try
{
// do stuff
result = true;
}
catch (Exception)
{
result = false;
}
return new StrategyResult<bool>
{
Value = result
};
}
}
Couple things to note here. First is the RegisterActionAttribute:
[AttributeUsage(AttributeTargets.Class)]
public sealed class RegisterActionAttribute : Attribute
{
public StrategyAction StrategyAction { get; }
public RegisterActionAttribute(string actionName, Type targetType, Type returnType, params string[] depdencies)
{
StrategyAction = new StrategyAction
{
Name = actionName,
StrategyType = targetType,
ResponseType = returnType,
Dependencies = depdencies
};
}
}
Then the interfaces:
public interface IStrategy<T>
{
IStrategyResult<T> Execute(ISerializable info = null);
}
public interface IStrategyResult<T>
{
bool IsValid { get; set; }
T Value { get; set; }
}
All fairly straight forward. The goal here is just to attach some meta-data to the class when it is loaded. The loading happens via unity using a wrapper that simply loads the assemblies in the bin directory using a file search pattern and adds it to a singleton class with a collection of StrategyActions. I don't need paste all the unity code here as I know it works and registers and resolves the assemblies.
So now to the meat of the question. I have a function on the singleton that executes actions. These are applied with Unity.Interception HandlerAttributes and passed a string like so (I can post the code for this but I didn't think it was relevant):
[ExecuteAction("MyPlugin")]
The handler calls the following execute function on the singleton class to "execute" functions that are registered (added to the collection).
public dynamic Execute(string action, params object[] parameters)
{
var strategyAction = _registeredActions.FirstOrDefault(a => a.Name == action);
if (strategyAction == null)
return null;
var type = typeof (IStrategy<>);
var generic = type.MakeGenericType(strategyAction.StrategyType);
var returnType = typeof (IStrategyResult<>);
var genericReturn = returnType.MakeGenericType(strategyAction.ResponseType);
var instance = UnityManager.Container.Resolve(generic, strategyAction.Name);
var method = instance.GetType().GetMethod("Execute");
return method.Invoke(instance, parameters);
}
This execute is wrapped in an enumerator call which returns a collection of results, which sorts to manage dependencies and what not (see below). These values are referenced by the caller using the Value property of ISTrategyResult{T} to do various things defined by other business rules.
public List<dynamic> ExecuteQueuedActions()
{
var results = new List<dynamic>();
var actions = _queuedActions.AsQueryable();
var sortedActions = TopologicalSort.Sort(actions, action => action.Dependencies, action => action.Name);
foreach(var strategyAction in sortedActions)
{
_queuedActions.Remove(strategyAction);
results.Add(Execute(strategyAction.Name));
}
return results;
}
Now mind you, this works, and I get the return type that is specified by the plugins RegisterAction attribute. As you can see I am capturing the Type of the plugin and the return type. I am using the "generic" variable to resolve the type with unity through the use of MakeGenericType, which works fine. I am also creating a generic representing the return type based on the type from the collection.
What I don't like here is having to use dynamic to return this value to a function. I can't figure out a way to return this as a IStrategyResult{T} because obviously the caller to "dynamic Execute(..." can not, at run-time, imply return type of the function. I mulled around with making the call to Execute with a MakeGenericMethod call as I actually have the expected type the StrategyAction. It would be cool if I could some how figure out away to return a strongly typed result of IStrategyResult{T} while determining the type of T during the call.
I do understand why I cannot do this with my current implementation I am just trying to find a way to wrap all this functionality without using dynamic. And was hoping somebody could provide some advice that might be useful. If that means wrapping this with other calls to non-generic classes or something like that, that would be fine as well if that is the only solution.
You need a more sweeping refactor than just figure out how to call your plugin.
There's no need for the [RegisterAction] attribute to hold targetType and returnType, these parameters to the attribute can easily get out of sync with code, making them a potential hole to fall into.
Then think from the other side of your setup: how do you consume the data, what do you do with your IStrategyResult<> - does it really have to be generic or there is a specific way you could encapsulate the type of results? I can't quite imagine a plugin system that returns "anything" to the host. The hint is really in your dynamic Execute(...) - your parameters and your result have both lost their strong typing, showing you that strong-typing the plugin is not helping with anything. Just use object or - better - make a StrategyResult class instead of the current interface and provide whatever properties are necessary there (I've added a few frivolous examples), such as:
public class StrategyResult{
public object Result{get;set;}
public Type ResultType {get;set;}
// frivolous examples
public bool IsError {get;set;}
public string ErrorMessage {get;set;}
// really off-the-wall example
public Func<StrategyHostContext,bool> ApplyResultToContext {get;set;}
public StrategyResult(){
}
public StrategyResult FromStrategy(IStrategy strategy){
return new StrategyResult{
ResultType = strategy.ResultType
}
}
public StrategyResult FromStrategyExecute(IStrategy strategy, ISerializable info = null){
var result = FromStrategy(strategy);
try{
strategy.Execute(info);
} catch (Exception x){
result.IsError = true;
result.ErrorMessage = x.Message;
}
}
}
Then your IStrategy becomes:
public interface IStrategy{
Type ResultType {get;}
void Initialize(SomeContextClassMaybe context);
StrategyResult Execute(ISerializable info = null);
}
You can also change your attribute to make it more efficient to load large plugins:
[AttributeUsage(AttributeTargets.Assembly)]
public sealed class AddinStrategyAttribute : Attribute
{
public Type StategyType {get; private set;}
public AddinStrategyAttribute(Type strategyType){
StrategyType = strategyType;
}
}
... and use the attribute like so:
[assembly:AddinStrategy(typeof(BoolStrategy))] // note it's outside the namespace
namespace MyNamespace{
public class BoolStrategy: IStrategy{
public Type ResultType { get{ return typeof(bool);}}
public void Initialize (SomeContextClassMaybe context){
}
public StrategyResult Execute(ISerializable info = null){
return StrategyResult.FromStrategyExecute(this,info);
}
}
}
Assuming that the caller of ExecuteActions does not have any knowledge about the T in any of the plugins or results and must work with dynamic or object anyway, then the following may work:
Infrastructure:
public interface IStrategy
{
IStrategyResult Execute(ISerializable info = null);
}
public interface IStrategyResult
{
bool IsValid { get; }
dynamic Value { get; }
}
public class StrategyResult<T> : IStrategyResult
{
public T Value { get; private set; }
public StrategyResult(T value) { this.Value = value; }
public bool IsValid { get { throw new NotImplementedException(); } }
dynamic IStrategyResult.Value { get { return this.Value; } }
}
[AttributeUsage(AttributeTargets.Class)]
public sealed class RegisterActionAttribute : Attribute
{
public List<string> Dependencies { get; private set; }
public RegisterActionAttribute(params string[] depdencies)
{
this.Dependencies = new List<string>(depdencies);
}
}
public class StrategyAction
{
public string Name;
public List<string> Dependencies;
}
public abstract class BasePlugin<T> : IStrategy
{
public IStrategyResult Execute(ISerializable info = null)
{
return new StrategyResult<T>(this.execute(info));
}
protected abstract T execute(ISerializable info);
}
Example plugin:
[RegisterAction]
public class MyFirstPlugin: BasePlugin<bool>
{
protected override bool execute(ISerializable info = null)
{
try
{
// do stuff
return true;
}
catch (Exception)
{
return false;
}
}
}
[RegisterAction("MyFirstPlugin")]
public class MySecondPlugin: BasePlugin<string>
{
protected override string execute(ISerializable info = null)
{
try
{
// do stuff
return "success";
}
catch (Exception)
{
return "failed";
}
}
}
Example execution engine:
public class Engine
{
public List<StrategyAction> registeredActions = new List<StrategyAction>();
private List<StrategyAction> queuedActions = new List<StrategyAction>();
public IStrategyResult Execute(string action, ISerializable info = null)
{
if (this.registeredActions.FirstOrDefault(a=>a.Name == action) == null) return null;
// This code did not appear to be used anyway
//var returnType = typeof (IStrategyResult<>); //var genericReturn = returnType.MakeGenericType(strategyAction.ResponseType);
var instance = (IStrategy) UnityManager.Container.Resolve(typeof(IStrategy), action);
return instance.Execute(info);
}
public List<IStrategyResult> ExecuteQueuedActions()
{
var results = new List<IStrategyResult>();
var actions = this.queuedActions.AsQueryable();
var sortedActions = TopologicalSort.Sort(actions, action => action.Dependencies, action => action.Name);
foreach(var strategyAction in sortedActions)
{
this.queuedActions.Remove(strategyAction);
results.Add(Execute(strategyAction.Name));
}
return results;
}
}
Note that when the plugins are loaded, the RegisterActionAttribute information along with the name of the plugin type loaded need to be combined into a StrategyAction instance and loaded into the registeredActions field of the engine.
The above allows the plugins to work with strong types but still allows the engine to deal with a variety of types. If you need the engine to work with more strongly typed data, then please provide an example of how the callers of ExecuteQueuedActions are expected to work with the results from ExecuteQueuedActions.
You got into this pickle by giving your RegisterActionAttribute constructor the returnType argument. Since you have only one Execute() method, you are forced to deal with the fact that the return type can be different types.
Using dynamic is about as good as it gets. You can make Execute() generic but then you'll have to deal with a mismatch between its type parameter and the attribute's ResponseType. Not one that the compiler can catch, this fails at runtime. It isn't generic.
Frankly, this strongly sounds like one flexibility too many. At the risk of interpreting the point of having a return type incorrectly, the outcome of a "registration action" is rather boolean. It worked or it didn't work. And is in fact the way you implemented it, your first plugin snippet does return bool.
With very high odds that you should not use bool either. Failure ought to make a bang, you'd throw an exception.
Why not define a super interface IStrategyResult like this:
interface IStrategyResult
{
Type ReturnType { get; }
}
interface IStrategyResult<T> : IStrategyResult
{
// your code here
}
Then define your execute like this:
public IStrategyResult Execute(string action, params object[] parameters)
And have your StrategyResult : IStrategyResult<T> class set the property to return typeof(T)
By convention you could assume (or enforce using inheritance on an abstract StrategyResult<T> : IStrategyResult<T> class) the T to be the same as the ReturnType property of the non-generic IStrategyResult interface.
public class Address
{...}
public class Object1
{
public Address Address {get;set;}
}
public class Object2
{
public Address Address {get;set;}
}
public UpdateAddress(Address address)
{
address = new Address();
}
//calling
var obj1 = new Object1();
UpdateAddress(obj1.Address);
//obj1.Address IS NULL
I cannot have my 2 classes inherit from a baseclass that has Address property (long story)
I was under the impression that when passing objects into methods they are by reference and my obj1.Address will have a new one and not be null if i am passing that property into a method.
If my assumption is wrong and it seems to be about object not being passed by reference in this instance.
How can i have a generic method that I can update a property that is the same across all my objects (I know I can return a new address object but I prefer to be passed in instead of returning)
Can this also be done by passing T<>?
UPDATE - Actual Code
Calling the methods
bool isVendorIdFromModel = UpdateVendor(entity.ExpenseVendor, entity.ExpenseVendorId, model, isNew, context);
if (isVendorIdFromModel)
{
entity.ExpenseVendorId = model.VendorId;
}
private static bool UpdateVendor(ExpenseVendor vendor, int? entityVendorId, ExpenseBaseModel model, bool isNew, ELMSContext context)
{
if (model.VendorId.HasValue)
{
if (entityVendorId != model.VendorId)
{
return true;
}
UpdateVendorInfo(model, vendor);
}
else
{
if (isNew && !string.IsNullOrEmpty(model.VendorName))
{
vendor = new ExpenseVendor
{
...
};
context.ExpenseVendors.Add(vendor);
}
if (vendor != null)
{
UpdateVendorInfo(model, vendor);
}
}
return false;
}
private static void UpdateVendorInfo(ExpenseBaseModel model, ExpenseVendor vendor)
{
vendor.Name = model.VendorName;
vendor.Address1 = model.Address1;
vendor.Address2 = model.Address2;
vendor.City = model.City;
vendor.PostalCode = model.PostalCode?.Replace(" ", string.Empty);
vendor.ProvinceId = model.ProvinceId;
}
Usual options:
shared base class (if you can change code and class hierarchy)
shared interface (if you can can change code, but no class hierarchy)
pass lambdas for getter/setter
use reflection and set by name
Since it sounds like you can't change the source lambda option may be the easiest. Following is option to "set" (when you replace whole object):
public void UpdateAddress(Action<Address> addressSetter)
{
addressSetter(new Address());
}
//calling
var obj1 = new Object1();
UpdateAddress(address => obj1.Address = address);
If you need to set properties of such object instead of replacing - pass get delegate:
public void UpdateAddress(Func<Address> addressGetter)
{
addressGetter().Street = "Dark alley";
}
UpdateAddress(address => obj1.Address);
Or use both. You can even combine them into helper class so it look close to properties (check out adapter pattern.
Note: generics not going to help you unless you can add common interface (but in that case you probably don't need generics at all).
If UpdateAddress only returns an address then change it to:
public Address UpdateAddress()
{
// set up address
return address;
}
var obj1 = new Object1();
obj1.Address = UpdateAddress();
Passing by reference and manipulating the contents of a parameter is a code smell. Write methods that return values and set the property that way.
I have the following issue related to reflection , I have a method which looks like this :
[TestMethod()]
public void steamAccess()
{
testRead = new TestRead();
SteamMap a = new SteamMap();
// Preparing the parameters of the CSV actions
a.writeMessageParams.UIItemEditText = TestContext.DataRow["SearchQuery"].ToString();
//Read and Execute the TestMethod
testRead.Read(a, TestContext);
}
This is a CodedUITest, SteamMap is a class (uiTest map).
WriteMessageParams is a class, actually the real method is WriteMessage but this class allows me to override the string that gets used into my tests by the WriteMessage method, and I plan to make this part of the code more dynamically in the Read method. :
a.writeMessageParams.UIItemEditText = TestContext.DataRow["SearchQuery"].ToString();
My problem happens in testRead.Read context as follows :
When this method is running I have access to all actions from the respective instance ( a in my case ) and if they are supposed to have to use a a.writeMessageParams.UIItemEditText context I know it, how I get the info isn't the problem, the problem is how to make the previously mentioned code to run dynamically as I have tried :
/* I've done this because I know that each method that is supposed to end up with Params, for example a method called WriteMessage, it's class is called WriteMessageParams*/
public void Read(object obj, TestContext testContext)
{
//simplified code
//trying to access/get to the current instance's WriteMessageParam class
Object testObj = obj.GetType().GetMember(subMethod.Code + "Param");
//null
MessageBox.Show(testObj.GetType().ToString());
// trying to access the UIItemEditText field ( which is declared as public) and modify it accordingly
FieldInfo subMethodField = testObj.GetType().GetField("UIItemEditText");
subMethodField.SetValue(testObj,testContext.DataRow[subMethod.CsvColumn].ToString());
}
I've had a read over this article and tried few things
https://msdn.microsoft.com/en-us/library/6z33zd7h%28v=vs.110%29.aspx
My problem is that I have the object of an instance and I try to access this object's class and modify that class's field .
I'd appreciate any help,
Thanks
Edit 1:
This is how the class I'm trying to access looks like :
public partial class SteamMap
{ //simplified to what classes/methods interest me
public virtual writeMessageParams writeMessageParams
{
get
{
if ((this.mwriteMessageParams == null))
{
this.mwriteMessageParams = new writeMessageParams();
}
return this.mwriteMessageParams;
}
}
public class writeMessageParams
{
#region Fields
/// <summary>
/// Type 'test' in text box
/// </summary>
public string UIItemEditText = "test";
#endregion
}
}
Edit 2 - I've tried by using GetNestedType, still no success....
Object testObj = obj.GetType().GetNestedType("writeMessageParams",BindingFlags.Public);
MessageBox.Show(testObj.GetType().ToString());
If I understand you, you have a class like
public partial class SteamMap
{
private writeMessageParams mwriteMessageParams ;
public virtual writeMessageParams writeMessageParams1
{
get
{
if ((this.mwriteMessageParams == null))
{
this.mwriteMessageParams = new writeMessageParams();
}
return this.mwriteMessageParams;
}
}
public class writeMessageParams
{
public string UIItemEditText = "test";
}
}
(your code doesn't compile because you have writeMessageParams both as the class and the property, so I have changed the property to writeMessageParams1)
And you want to change UIItemEditText, which you can do like
public void UpdateUI(object obj, string newValue)
{
var property = obj.GetType().GetProperty("writeMessageParams1");
var writeMessageParams1 = property.GetValue(obj);
var uiFld = wp.GetType().GetField("UIItemEditText");
uiFld.SetValue(writeMessageParams1, newValue);
}
which can be called like
SteamMap sm = new SteamMap();
Write(sm, "Hello");
The key is to use .GetProperty for the property and .GetField for the field.
Given the following code;
public class CustomControl {
private object _dataItem;
public object DataItem {
get { return _dataItem; }
set { _dataItem = value; }
}
public void Update(ref string t) {
t = "test";
}
}
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
string prop = anyObject.anyProperty;
ctrl.Update(ref prop);
anyObject.anyProperty = prop;
}
}
How can I change it so that the DataItem property is itself a reference, allowing you to pre-emptively set it to point to a variable thus allowing you to call Update() without any parameters.
So the Consume class would then look similar to;
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
ctrl.Update();
// anyObject.anyProperty has been updated to "test"
}
}
So the assigment of anyObject.anyProperty is then handled internally within CustomControl
You need to store the act of setting something to a string, so store an Action<string>:
public class CustomControl {
public Action<string> SetData { get; set; }
public void Update() {
// TODO nullity check
SetData("test");
}
}
Then Consume would look like:
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
// store {the act of setting this property of this object to a string}
ctrl.SetData = s => anyObject.anyProperty = s;
ctrl.Update();
}
}
The Update call will set anyObject.anyProperty to test. Note that you are storing specifically the act of setting this property of the particular anyObject you refer to in the assignment to SetData.
To expand on the lambda: we want to create a value of type Action<string>, that is, a thing which takes a string and returns no result. Such a thing is going to be executable code. Prior to C# 3, to create a 'value' that was executable code, we would have had to do something like:
ctrl.SetData = delegate(string s) { someObject.SomeProperty = s; };
With this syntax it's more obvious that we're creating a method - it has a { } delimited body, it has statements in it, and it's clear there is a string parameter that is used by the body.
One thing achieved by lambda expressions in C# 3 is the ability to condense this down; loosely, the whole of
// not compilable code
delegate(parameters) { body; }
can be replaced with
// not compilable code
(parameters) => body;
and in the case where there's only one parameter
// not compilable code
parameter => body;
which is what we have here: the expression assigned to ctrl.SetData is a piece of behaviour that accepts a string (s) and sets anyObject.anyProperty to that string. The real power is in the way the C# compiler can work out the types to it know we're creating an Action<string>.
At first I didn't understand what you're trying to do. What you're looking for is the Adapter or Facade pattern. That is, you have an object with a particular interface, but you need to adapt it to a different interface or provide a simpler interface.
One way to implement these patterns is to use composition and delegate the new interface to methods on the existing interface.
public interface IUpdatable<U>
{
void Update( U newValue );
}
public abstract class CustomControl<T,U> : IUpdatable<U>
where T : Control
{
private T Control { get; set; }
protected CustomControl( T control )
{
this.Control = control;
}
public abstract void Update( U newValue );
}
public class TextBoxFacade : CustomControl<TextBox,string>, IUpdatable<string>
{
public TextBoxFacade( TextBox textbox ) : base(textbox) { }
public override void Update( string newValue )
{
this.Control.Value = newValue;
}
}
I would like to automatically generate SQL statements from a class instance. The method should look like Update(object[] Properties, object PrimaryKeyProperty). The method is part of an instance (class, base method - generic for any child). Array of properties is an array of class properties, that will be used in update statement. Property names are equal to table field names.
The problem is that I can't get property names.
Is there any option to get a property name inside class instance?
sample:
public class MyClass {
public int iMyProperty { get; set; }
public string cMyProperty2 { get; set; }
{
main() {
MyClass _main = new MyClass();
_main.iMyProperty.*PropertyName* // should return string "iMyProperty"
{
I am aware of PropertyInfo, but I don't know hot to get the ID of a property from GetProperties() array.
Any suggestion?
Just wrote an implementation of this for a presentation on lambdas for our usergroup last Tuesday.
You can do
MembersOf<Animal>.GetName(x => x.Status)
Or
var a = new Animal()
a.MemberName(x => x.Status)
the code:
public static class MembersOf<T> {
public static string GetName<R>(Expression<Func<T,R>> expr) {
var node = expr.Body as MemberExpression;
if (object.ReferenceEquals(null, node))
throw new InvalidOperationException("Expression must be of member access");
return node.Member.Name;
}
}
Link to the presentation and code samples.
Also in SVN (more likely to be updated): http://gim-projects.googlecode.com/svn/presentations/CantDanceTheLambda
I found a perfect solution in This Post
public static string GetPropertyName<T>(Expression<Func<T>> propertyExpression)
{
return (propertyExpression.Body as MemberExpression).Member.Name;
}
And then for the usage :
var propertyName = GetPropertyName(
() => myObject.AProperty); // returns "AProperty"
Works like a charm
You can do something like this:
Type t = someInstance.getType();
foreach (MemberInfo mi in t.GetMembers())
{
if (mi.MemberType == MemberTypes.Property)
{
Console.WriteLine(mi.Name);
}
}
to get all the property names for instance's type.
You can get the name (I assume that's what you meant by ID) of a property using PropertyInfo.Name. Just loop through the PropertyInfo[] returned from typeof(className).GetProperties()
foreach (PropertyInfo info in typeof(MyClass).GetProperties())
{
string name = info.Name;
// use name here
}
Since you already have an explicit handle to the specific property you want, you know the name - can you just type it?
Not 100% sure if this will get you what you're looking for, this will fetch all properties with [Column] attribute inside your class:
In the datacontext I have:
public ReadOnlyCollection<MetaDataMember> ColumnNames<TEntity>( )
{
return this.Mapping.MappingSource.GetModel(typeof(DataContext)).GetMetaType(typeof(TEntity)).DataMembers;
}
Fetching the table column-names that are properties inside the class:
MyDataContext db = GetDataContext();
var allColumnPropertyNames = db.ColumnNames<Animal>().Where(n => n.Member.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), false).FirstOrDefault() != null).Select(n => n.Name);
Let's say (from the first sample, method update of a class MyClass):
public class MyClass {
public int iMyStatusProperty { get; set; }
public int iMyKey { get; set; }
public int UpdateStatusProperty(int iValue){
this.iMyStatusProperty = iValue;
return _Update( new[iMyStatusProperty ], iMyKey); // this should generate SQL: "UPDATE MyClass set iMyStatusProperty = {iMyStatusProperty} where iMyKey = {iMyKey}"
}
{iMyStatusProperty} and {iMyKey} are property values of a class instance.
So, the problem is how to get property name (reflection) from a property without using names of properties as strings (to avoid field name typos).