I created a class where the main task is get data from the DB and mapping it to some object. The problem is the same class needs to map different datareader to different object. So, what I tried to do is to get out the mapping method using delegates.
Here is part of my code. See the important rows in bold.
public class GetDetails<T>
{
**public delegate void DelegateMapping(T position, IDataReader reader);**
**public DelegateMapping mappingMethod;**
public T Get(T instance)
{
//Get IDs and Add to list
_db.ExecuteReader(storedProcedure.ToString(), CommandType.StoredProcedure, reader =>
{
while ( reader.Read() )
{
**mappingMethod(instance, reader);**
}
}, parameterList.ToArray());
return instance;
}
}
And this is the class which is calling and using the "GetDetails" class
public class PositionDB : DbBase
{
public Position GetPositionDetails(string IDs)
{
GetDetails<Position> getIDs = new GetDetails<Position>(base.db);
getIDs.storedProcedure = StoredProcedure.NET_ADM_GetPositionDetails;
//Set the Delegated Method
**getIDs.mappingMethod = MappingPositionDetails;**
//Set Parameters
getIDs.parameterList.AddInParam("PositionIds", DbType.String, IDs);
//Return the PositionId Collection
return getIDs.Get(new Position());
}
**private void MappingPositionDetails(Position position, IDataReader reader)
{
position.Id = reader["CompPositionId"];
position.Description = reader["Description"];
position.ExpirationDate = reader["ExpirationDate"];
position.Title = reader["Title"];
}**
}
The code is working OK.
The questios are:
Did I use delegate correctly?
This kind of solution can cause problems in the future (performance)?
There is another better solution?
Thank you very much
Sebastian
To specifically answer your questions:
Yes, you did use delegates correctly
Yes, it can cause problems due to concurrency issues while multithreading
I think so, I detailed one possible solution below
I would propose three changes:
Move the delegate call into the method (concurrency issues, one thread could change the mapping delegate while another thread tries to access it, now trying to map a reader to completely different object than provided)
Use the already present generic Action/Func delegates, no need to define your own.
Use lambda expressions to define the mapping, no need for extra methods
Notice: 2 and 3 will need at least .net 3.5.
Employing these two proposals, your code would look like this:
public class GetDetails<T>
{
public T Get (T instance, Action<T, IDataReader> mappingMethod)
{
//Get IDs and Add to list
_db.ExecuteReader(storedProcedure.ToString(), CommandType.StoredProcedure, reader =>
{
while ( reader.Read() )
{
mappingMethod(instance, reader);
}
}, parameterList.ToArray());
return instance;
}
}
Now you can use this method in a multi-threaded environment as well.
Edit
just realized it's just part of the code. I corrected my proposal to take this into account.
Yes (There's some improvements you could make, see 3)
Not performance wise, maybe some issues in discoverability.
I would use polymorphism to eliminate the delegate completely for discoerability. Perhaps using an abstract method/class. Also depending on which .NET version you're developing for you can use lambdas and simpler types.
public Action<Position, IDataReader> Mapping { get; set; }
Then
getIDs.Mapping = (position, reader) =>
{
position.Id = reader["CompPositionId"];
position.Description = reader["Description"];
position.ExpirationDate = reader["ExpirationDate"];
position.Title = reader["Title"];
};
Related
This question already has answers here:
How enumerate all classes with custom class attribute?
(8 answers)
Closed 3 years ago.
I'm working on a command tool in C#, although not for a terminal command-line. I have read the documentation on reflection and attributes but I'm not sure exactly what the "right" way to go about this is.
The problem isn't very complicated, but it needs to be easily extended. I need to just have Commands that are picked up and loaded in where their triggering strings are checked and if they match, methods are called. How I went about it just as a proof-of-concept was:
[System.AttributeUsage(System.AttributeTargets.Class)]
public class CommandAttribute : Attribute
{
public string Name { get; private set; } //e.g Help
public string TriggerString { get; private set; } //e.g. help, but generally think ls, pwd, etc
public CommandAttribute(string name, string triggerStrings)
{
this.Name = name;
this.TriggerString = triggerString;
}
}
Now, I decorated the class and it will implement methods from an interface. Eventually there will be many commands and my idea is to make it easy for someone with minimal programming experience to jump in and make a command.
using Foo.Commands.Attributes;
using Foo.Infrastructure;
namespace Foo.Commands
{
[Command("Help", "help")]
public class Help : IBotCommand
{
// as an example, if the message's contents match up with this command's triggerstring
public async Task ExecuteAction()
}
}
This gets injected into the console app where it will load the commands and get passed messages
public interface ICommandHandler
{
Task LoadCommands();
Task CheckMessageForCommands();
}
Then, everything with a matching attribute will get loaded in and when a message is received, it will check its contents against all CommandAttribute decorated classes' triggering strings, and if it matches, call the method ExecuteAction on that command class.
What I've seen/tried: I understand how to use reflection to get custom attribute data, however I'm confused as to getting the methods and calling them, and how all of this should be configured to be fairly performant with reflection being used. I see CLI tools and chat bots that use a similar method, I just cannot peek into their handlers to see how these get loaded in and I can't find a resource that explains how to go about accessing the methods of these classes. Attributes may not be the right answer here but I'm not sure how else to go about it.
Really, my main question is:
How do I setup The CommandHandler to load all of the attribute-decorated classes and call their methods, and how they should be instantiated within it. I know the second piece may be a bit more subjective but would newing them up be improper? Should they somehow be added to DI?
My solution ended up just using the Activator and lists. I still need to tweak this for performance and run more extensive stress tests, but here is my quick code for it:
// for reference: DiscordCommandAttribute is in Foo.Commands library where all the commands are, so for now it's the target as I removed the base class
// IDiscordCommand has every method needed, so casting it as that means down the line I can call my methods off of it. The base class was just for some reflection logic I was testing and was removed, so it's gone
public void LoadCommands() // called in ctor
{
var commands =
from t in typeof(DiscordCommandAttribute).Assembly.GetTypes()
let attribute = t.GetCustomAttribute(typeof(DiscordCommandAttribute), true)
where attribute != null
select new { Type = t, Attribute = attribute };
foreach (var obj in commands)
{
_commandInstances.Add((IDiscordCommand)Activator.CreateInstance(obj.Type));
_commandAttributes.Add(obj.Attribute as DiscordCommandAttribute);
}
}
There is probably a more sugary way to handle adding the objects to the lists, and some other data structure besides Lists might be more suitable, I'm just not sure if HashSet is right because it's not a direct Equals call. Eventually I will genericize the interface for this class and hide all of this logic in a base class. Still a lot of work to do.
Currently, just putting a stopwatch start before calling LoadCommands shows that the entire load takes 4ms. This is with 3 classes and a pretty anemic attribute, but I'm not too worried about the scale as I want any overhead on launch and not during command handling.
Using some code I wrote for this answer, you can find all types that implement an interface, e.g. IBotCommand, and then retrieve the custom attribute:
public static class TypeExt {
public static bool IsBuiltin(this Type aType) => new[] { "/dotnet/shared/microsoft", "/windows/microsoft.net" }.Any(p => aType.Assembly.CodeBase.ToLowerInvariant().Contains(p));
static Dictionary<Type, HashSet<Type>> FoundTypes = null;
static List<Type> LoadableTypes = null;
public static void RefreshLoadableTypes() {
LoadableTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetLoadableTypes()).ToList();
FoundTypes = new Dictionary<Type, HashSet<Type>>();
}
public static IEnumerable<Type> ImplementingTypes(this Type interfaceType, bool includeAbstractClasses = false, bool includeStructs = false, bool includeSystemTypes = false, bool includeInterfaces = false) {
if (FoundTypes != null && FoundTypes.TryGetValue(interfaceType, out var ft))
return ft;
else {
if (LoadableTypes == null)
RefreshLoadableTypes();
var ans = LoadableTypes
.Where(aType => (includeAbstractClasses || !aType.IsAbstract) &&
(includeInterfaces ? aType != interfaceType : !aType.IsInterface) &&
(includeStructs || !aType.IsValueType) &&
(includeSystemTypes || !aType.IsBuiltin()) &&
interfaceType.IsAssignableFrom(aType) &&
aType.GetInterfaces().Contains(interfaceType))
.ToHashSet();
FoundTypes[interfaceType] = ans;
return ans;
}
}
}
public static class AssemblyExt {
//https://stackoverflow.com/a/29379834/2557128
public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly) {
if (assembly == null)
throw new ArgumentNullException("assembly");
try {
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException e) {
return e.Types.Where(t => t != null);
}
}
}
Note: If you create types at runtime, you will need to run RefreshLoadableTypes to ensure they get returned.
If you are concerned about IBotCommand implementors existing without the CommandAttribute, you can filter the ImplementingTypes, otherwise:
var botCommands = typeof(IBotCommand)
.ImplementingTypes()
.Select(t => new { Type = t, attrib = t.GetTypeInfo().GetCustomAttribute<CommandAttribute>(false) })
.Select(ta => new {
ta.Type,
TriggerString = ta.attrib.TriggerString
})
.ToDictionary(tct => tct.TriggerString, tct => tct.Type);
With an extension method for your command Types:
public static class CmdTypeExt {
public static Task ExecuteAction(this Type commandType) {
var cmdObj = (IBotCommand)Activator.CreateInstance(commandType);
return cmdObj.ExecuteAction();
}
}
You can use the Dictionary like:
var cmdString = Console.ReadLine();
if (botCommands.TryGetValue(cmdString, out var cmdType))
await cmdType.ExecuteAction();
Overall, I might suggest having a method attribute and having static methods in static classes for commands, so multiple (related?) commands can be bundled in a single class.
PS My command interpreters have help associates with each command, and categories to group commands, so perhaps some more attribute parameters and/or another IBotCommand method to return a help string.
I have a set of class objects that I can not touch. All of them have an ID property that I would like to access in other functions in a generic way.
For simplicities sake here is an example of my problem.
class Example1 {
int ID { get; set;}
}
class Example2 {
int ID { get; set; }
}
I am not able to edit either of these two classes or the library they are in.
I also have a function that expects an ID that can come from either Example1 or Example2. In order to handle this I have come up with a number of solutions but am curious what the proper way to solve this would be.
I could:
Use dynamic classes to access the various classes ID's.
Use reflection to pull out an ID parameter from any given type.
Use an odd inheritance by creating a new class so that Example1ViewModel : Example1, IIdentifiableObject and then expect IIdentifiableObject in my function and implement a copy constructor in Example1ViewModel to handle collecting the data
Write a separate filter function that can extract out the relevant parts from either class and provide the results.
None of these solutions seem particularly good to me. How should I be handling a many to one relationship like this in code and are there tools that C# provides to handle this?
possible solution using extension methods for the classes
public static class MyExtensions
{
public static int GetId(this Example1 ex)
{
return ex.Id;
}
public static int GetId(this Example2 ex)
{
return ex.Id;
}
}
You can add a static method using reflection:
public static int GetId(object obj)
{
Type type = obj.GetType();
return Convert.ToInt32(type.GetProperty("ID").GetValue(obj, null));
}
Then you can invoke it with any object to get the id property value.
Here is the solution that we ended up using and why.
We are using an inheritence structure that that takes the following two base classes:
FooExample
BarExample
and wraps them in the following
IExample
FooExampleModel : IExample
BarExampleModel : IExample
Both FooExampleModel and BarExampleModel have constructors which accept the class they are wrapping.
The importance of this is that it allows us to create methods accepting IExample instances without having to manipulate data beforehand. Additionally, unlike using dynamic types or reflection this solution provides us with compile time error checking.
Unfortunately using extension methods does not work. While it allows us to call the same method on two different object types like we wanted it does not allow those objects to be passed as Generic types to a seperate function.
The result of all of this is that this is now possible:
var foos = new List<FooExample>(); //Pretend there is data here
var bars = new List<BarExample>();
var examples = foos.Select((foo) => (IExample)new FooExampleModel(foo))
.Concat(bars.Select((bar) => (IExample)new BarExampleModel(bar)))
.ToList(); // Force evaluation before function call
DoSomethingOnIExamples(examples);
Besides that slightly gross LINQ query this appears to be the best way to accomplish this (DoSomethingOnIExamples(...) is a function accepting an IEnumerable<IExample> argument). Obviously this solution gets less nice as more types are added to this mix.
Let's say I have an interface called IConvertableModel and it helps me to convert some MVC models to/from DTO objects as shown below:
public class DisplayEditModel : IConvertableModel<Display>
{
[HiddenInput(DisplayValue = false)]
public int ObjectId { get; set; }
[StringLength(255)]
public string Description { get; set; }
public Display ToDto()
{
return new Display
{
Description = Description,
ObjectId = ObjectId,
};
}
public void SetFromDto(Display dto)
{
Description = dto.Description;
ObjectId = dto.ObjectId;
}
}
But there is one problem with this approach and that is it doesn't allow me do this :
var dto = _dtoRepository.GetFirstDto();
return new DisplayEditModel().SetFromDto(dto);
Instead I should do the following:
var dto = _dtoRepository.GetFirstDto();
var model = new DisplayEditModel();
model.SetFromDto(dto);
return model;
and this is adding extra two lines of code and little bit complexity in the long run.
What I am thinking is to convert SetFromDto method to something like this:
public DisplayEditModel SetFromDto(Display dto)
{
Description = dto.Description;
ObjectId = dto.ObjectId;
return this;
}
I think the benefit of this code is obvious but I also like to learn whether this harms code readability and leads to unexpected results for developers in the long run and if you think anything else, what would you recommend.
Note: Because of the interfaces reasons, I am not thinking to implement a constructor method.
A few thoughts, to begin with:
Adding lines of code is not the same as adding complexity. Having three statements, where each does a simple operation, is not necessarily harder to maintain or understand than a single statement with three operations inside of it.
When a method that begins with Set..., programmers will automatically assume that some stateful values of the target object are going to be changed by this method. It is rare for Set methods to have a return value. Property setters in C# actually "return" the original value passed into them, so you can chain setters:
int i = foo.A = 2;
So the precedent is generally against returning "this" from a set method specifically.
Chaining in general is most useful/desired when you're expecting several operations to be performed, one after the other. For example, C# provides nice initialization syntax so you can "chain" a bunch of different property setters on the same object:
var foo = new Foo { A = 1, B = 2 };
You can see how chaining is fulfilling the need to perform similar, grouped, repetitive operations that typically get performed all together. That is not the problem that you are trying to solve.
If your main gripe is that you don't like having three lines of code, why not just use a helper whose name indicates what you're trying to do?
TModel MapToModel<TModel, TDto>(TDto dto, TModel model)
where TModel : IConvertableModel<TDto>
{
model.SetFromDto(dto);
return model;
}
// usage:
var dto = _dtoRepository.GetFirstDto();
return MapToModel(dto, new DisplayEditModel());
... or even:
TModel CreateModel<TModel, TDto>(TDto dto)
where TModel : IConvertableModel<TDto>, new()
{
var model = new TModel();
return MapToModel(dto, model);
}
// usage:
var dto = _dtoRepository.GetFirstDto();
return CreateModel<DisplayEditModel>(dto);
This is simple, readable, and feasible, whereas the approach you're suggesting would break the IConvertableModel<Display> interface:
public interface IConvertableModel<TDto>
{
public TDto ToDto();
public ??? SetFromDto(TDto dto);
}
What would SetFromDto return? You would have to define another generic type on IConvertableModel.
public interface IConvertableModel<TDto, TModel> {
public TDto ToDto();
public TModel SetFromDto(TDto dto);
}
But this wouldn't really indicate that the SetFromDto method is necessarily returning itself, because it allows for a class that is not a TModel to implement IConvertableModel to convert between two other types.
Now, you could go out of your way to push the generics even farther:
public interface IConvertableModel<TDto, TModel>
where TModel : IConvertableModel<TDto, TModel>
{...}
But this still allows for some fudging, and the interface cannot guarantee that you are really returning "this" object. All in all, I'm not a big fan of that approach.
Rather than having DisplayEditModel have a get/set method for a Display object to get/set the values, just use a property that doesn't actually have a separate backing store:
public Display Display
{
get
{
return new Display
{
Description = Description,
ObjectId = ObjectId,
};
}
set
{
Description = value.Description;
ObjectId = value.ObjectId;
}
}
Now you can use an object initializer with this property when creating a model:
return new DisplayEditModel() { Display = dto };
This is a very javascript way of approaching this problem, though it has it's benefits. In the context of C#, it is a little bit strange though libraries such as LINQ do this to allow chaining together function calls.
My only worry about this, is that this has to be a class that does this consistently. Implementing a chaining function return pattern is not really a convenience as much as it is a design choice. The rule to follow in this case, would be to return this every time you mutate the object.
Chaining also may not be worth it performance wise. Something that can be done by wrapping all those operations into a single function is much faster. For instance:
MyVector.setX(1).SetY(1).SetZ(1).SetW(0)
is a lot slower than simply
MyVector.set(1, 1, 1, 0)
because now you are now doing excessive stack operations to do something fairly simple. It only becomes worth it on very large operations that take up the bulk of the computing time and make sense to chain together. For this reason, LINQ allows you to chain things together.
I wouldn't say that it necessary "harms" or is dangerous. We are in the world of a managed language, so we don't have direct access to that memory location (unlike C/C++). So I would just call it a design choice which can be fairly powerful in some cases and not so much in others.
As noted, chainable methods work fine but are not as common in C# as in some other languages. If the extra lines of code only happen in one place, I'd just leave it alone. If it's really bugging you or you do it a lot, then consider implementing a special constructor for it:
public void DisplayEditModel(Display dto)
{
this.SetFrom(dto);
}
or a static factory method:
public static DisplayEditModel CreateFrom(Display dto)
{
var model = new DisplayEditModel();
model.SetFrom(dto);
return model;
}
Either option has a clear intent, lets you create and return the object in a single line, and is idiomatic. It does require a few extra lines of code in DisplayEditModel, but I doubt it will be a serious problem.
From my C# 4.0 code, I want to execute some queries on Sybase and MSSQL. The database being used (or to be used) will be decided/known at runtime only.
I am using AseCommand and SqlCommand for Sybase and SQL respectively.
I decided to create generic method like this:
private Department ExecuteCommand<T>(T databaseCommand) where T : class
{
Department department = new Department ();
dynamic command = databaseCommand;
using (dynamic databaseReader = command.ExecuteReader())
{
if (databaseReader.HasRows)
{
while (databaseReader.Read())
{
department.Employees.Add(this.CreateDepartmentInstance(databaseReader));
}
}
}
command.Connection.Dispose();
return department;
}
Questions:
Is there better option other than dynamic?
What is usually the right way to know the type of the argument passed to the generic method?
Of course, I can write two separate methods for Sybase and SQL. But why to do so when something like dynamic is at disposal?
You do not necessarily need dynamic here, all you require is a common interface (which in this instance they both have):
private Department ExecuteCommand<T>(T databaseCommand) where T : IDbCommand
However, in this instance since you are not doing anything particularly interesting with type T (as far as I can see), the following method signature would suffice:
private Department ExecuteCommand(IDbCommand databaseCommand)
In general, if there is no common interface, I'd recommend using the facade pattern and simply delegating method calls through to equivalents on the actual implementation.
It looks like AseCommand and SqlCommand both implement IDbCommand, so you just need to change the type constraint:
private Department ExecuteCommand<T>(T databaseCommand) where T : IDbCommand
{
Department department = new Department();
using (IDataReader databaseReader = databaseCommand.ExecuteReader())
{
if (databaseReader.HasRows)
{
while (databaseReader.Read())
{
department.Employees.Add(
this.CreateDepartmentInstance(databaseReader));
}
}
}
command.Connection.Dispose();
return department;
}
I Imagine you'd also need to change CreateDepartmentInstance to accept an IDataReader if it doesn't already.
Though as rich.okelly points out, it doesn't look like there's really a reason to use generics here in the first place.
Answer to #2:
if (typeof(T) == typeof(object) ) {
// Check for IEnumerable
}
Replace object with whatever type you would like to check for.
In your case, using a common interface will do just fine.
In general, if you want to find out the type of an object you can always use the is and as-Operators.
private Department ExecuteCommand<T>(T databaseCommand) where T : class
{
Department department = new Department ();
var command = databaseCommand;
using (var databaseReader = command.ExecuteReader())
{
if ((databaseReader as IDataReader).HasRows)
{
while ((databaseReader as IDataReader).Read())
{
department.Employees.Add(this.CreateDepartmentInstance(databaseReader));
}
}
}
command.Connection.Dispose();
return department;
}
Not verified in VS, but it should work.
I'm trying to create a wrapper around List to do some specific things I want, such as compute max min, extract specific values from some elements, etc.
I start with
public struct datum {
public UInt32[] chan;
public UInt64 sample_number;
public UInt32 time;
public UInt32 source_sector;
}
public class dataSet : List<datum> {
bool dirty=true;
....
}
the methods are typically like this (I want to know if the list has been modified as I have a max()/min() function that only parses the data when it has been modified and caches the values to reuse if the List has not been modified)
public new void Add(datum x ) {
base.Add(x);
this.dirty = true;
}
However, I'm not sure how to create a constructor. This syntax does not work.. how can I get this type of behavior?
public dataSet(int count) {
this = (dataSet) new List<datum>(count);
}
I also have this constructor, which seems to work fine (no compilation errors) though untested
public dataSet(List<datum> data) {
this.AddRange(data);
}
I came across a post that said that you should use a Collection and a List is used for speed. Though I need the speed, and I'm not sure why a Collection would be better?
--UPDATE--
I don't want to use linq as you can't create something that computes max/min simultaneously as efficiently as this:
public void recalculateMaxMin() {
foreach (var d in data) {
for (int i = 0; i < 16; i++) {
if (d.chan[i] > max[i]) max[i] = d.chan[i];
if (d.chan[i] < min[i]) min[i] = d.chan[i];
}
}
}
Thnx
I'm trying to create a wrapper around List to do some specific things I want, such as compute max min, extract specific values from some elements, etc.
Don't. Just use LINQ to Objects. That's what it was designed for:
var list = new List<int> { 10, 20, 30 };
var average = list.Average();
var max = list.Max();
// etc
In general, I would advise against deriving from List<T> anyway - that's not what it was designed for. However, if you must, you just chain from one constructor to a base constructor:
public dataSet(int count) : base(count)
{
// Add in any extra code you want to here. Probably none in this case.
// It would execute *after* the base constructor call.
}
See my article on constructors for more information about constructor chaining.
(I'd also strongly advise you to change the name - dataSet doesn't comply with .NET naming conventions, and DataSet would mean something else entirely to most .NET developers.)
You can never ever set "this" to something in C#. I think you are looking for this:
public dataSet(int count)
: base(count)
{ }
However in my opinion you should take a look at "System.Linq" namespace. I think what you are trying to implement has been done before by Microsoft. 'Select', 'Join', 'Where' and many other clauses has been already implemented in Linq. Also you can use "INotifyCollectionChanged" interface to implement the dirty thing.
Here are some references:
INotifyCollectionChanged
Linq
If you realy need to implement a complete List class with a new behavior, implementing "System.Collections.Generic.IList" interface is the only thing that will rock your idea in an advanced and perfect way. It's more customizable than inheriting from the List class and trying to change everything you have no access to.
Hope it helps
Cheers
public dataSet(int count)
: base(count) {
}
You can call the base type's constructor using base()
public dataSet(int count) : base(count)
{
// no need to implement anything here. base(count) will call the base
// type's constructor
}