Let's say I have two classes that look like this:
public class ByteFilter
{
private Func <int, byte[]> readBytes;
private Action<byte[]> writeBytes;
public ByteFilter(Func <int, byte[]> readBytes, Action<byte[]> writeBytes)
{
this.readBytes = readBytes;
this.writeBytes = writeBytes;
}
}
public class PacketFilter
{
private Func<Packet> readPacket;
private Action<Packet> writePacket;
Public PacketFilter(Func<Packet> readPacket, Action<Packet> writePacket)
{
this.readBytes = readPacket;
this.writeBytes = writePacket;
}
}
Either class may be instantiated at runtime (via Activator.CreateInstance) to perform a filtering function. The read and write methods will be hooked up at runtime to methods from other classes that will provide and accept byte arrays or packets.
Within each filter is additional code that performs the filtering function:
public void Process()
{
while (!done)
{
byte[] data = ReadBytes(); // or ReadPacket()
// perform filtering on data
WriteBytes(data); // or WritePacket()
}
}
If only one of the above constructor signatures will be present in each filter, how do I determine (using Reflection) which constructor signature is present, so that I can hook up the appropriate methods at runtime?
Note: If I'm daffy and doing this the wrong way, I'd like to know that too.
Can't you do something like?
bool packetConstructor =
typeof(PacketFilter).GetConstructors()
.Any(c => c.GetParameters()
.Any(p => p.ParameterType
== typeof(Func<Packet>)));
replacing typeof(PacketFilter) with appropriate instance.
An option that has not been mentioned is to use Fasterflect, a library created to make reflection easier and faster where possible.
It also has a couple of features built on top of the core reflection capabilities, one of which is the ability to construct objects when you don't know what constructors are available.
var instance = typeof(PacketFilter).TryCreateInstance( new { Foo = "Bar" } );
There are also overloads for passing in a dictionary of named values or discrete name and value arrays. The latest code also provides extensions for constructing objects just from an ordered list of values, matching them in order to parameters by their type.
Fasterflect will automatically pick the constructor with the most matching arguments. If it's unable to use a value it'll try to set a matching property after construction. And you have the option of requiring all values to be used.
Disclaimer: I'm a contributor to the project.
You can enumerate the constructors (to get the one constructor) and then enumerate the parameters of the constructor. Since the parameters are expected to be generic types, you then need to enumerate the generic type parameters for each generic constructor parameter. Note that all of this is very hacky and I would recommend finding a better solution. Reflection is a powerful tool and using it introduces complexity; if there is a less complex solution (such as a factory pattern, perhaps), that would be preferable. It's also possible that your need to solve this particular problem reflects excessive complication in your existing design. If you simplify the original design, you may find that the technical problem goes away.
Related
I've been trying to figure out a way to deal with property mapping and naming programmatically. The thing is that I don't want to have to change multiple portions of code to be able to extend the map. The code I have right now is like this:
public static class Names
{
public const string Property = "propertyNameToBeUsedInJson";
}
...
switch(propertyName)
{
case Property:
user.propertyToBeMapped = json.propertyValue;
break;
}
What I really wanted was to be able to have some sort of dictionary where I could do something like:
Dictionary<string, Action>() { {"propertyNameToBeUsedInJson", <Class of User>.propertyToBeMapped} };
That means I would be delegating access to a property of a Class, not to a concrete object. This way I can iterate over this dictionary and if it contains the key I'm looking for, then I just go and change the property pointed by the value.
I think that a overhead during initialization is ok, but I don't want to use Reflection on a per call basis.
The questions is: Is it possible to use the second way having in mind the statement above? If so, how should I go for it?
Just to summarize the comments:
It is definitely possible to do it with a dictionary, but properties cannot be used quite this way. Remember that properties are just syntactic sugar so you don't have to write get/set methods yourself. The best way to get it into a dictionary is probably by wrapping it into a delegate:
new Dictionary<string, Func<YourClass, string>>()
{
{"propertyNameToBeUsedInJson",
instance => instance.YourProperty}
};
Then, you would use it very easily like this (error checking omitted):
user.propertyToBeMapped = dictionary[propertyName](yourClassInstance);
This will only work if the instance is always the same class. If not, the first parameter of the Func would have to be some base class (maybe even object) and then the delegate would have to do some type-checking and conversion.
I just updated Visual Studio 2013 and I noticed that in the project template for an MVC application the ApplicationDbContext class now has a static method that just calls the constructor:
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
This seems like clutter to me but I imagine that there is some semantic reason that I should now start using ApplicationDbContext.Create() instead of new ApplicationDbContext(). Are there any benefits to doing so?
Actually. yes.
In your specific case, wrapping it thusly allows you to quickly start bolting on logic, such as making the ApplicationDbContext and singleton or handling an exception in a common way for the whole application. Since a constructor cannot return null, this can be very important to be able to catch an exception and return null.
Tuple.Create is the prime example of generic inference, which does not work with Constructors. This allows you say
Tuple.Create(Item1, Item2.. ItemN);
And the let the compiler infer types, rather than
new Tuple<T1, T2...Tn>(Item1, Item2...ItemN);
Which is more verbose, and takes a bit more work if you want to switch out one of those types.
There is also the case of Anonymous types, which cannot be specified explicitly and thus cannot be used in new statements. I have specifically had occasion where, while searching assemblies for a specific Attribute to link a command structure for, I wanted to make an enumerable (a Queue, in this case) out of an anonymous type during the search to pair class references with their constructor and string arguments, rather than looking these up every time they're needed. Since I can again use Generic inference in a method, I was able to wrap the constructor in an extension method and get the job done.
There are also cases for singleton patterns, wherein you want the "GetInstance" method to usually create a value, or get one if it exists. May not qualify since it does slightly more than wrap a constructor.
In addition, there are plenty of cases where you may want to control implementation procedures, such as forcing them onto other threads, logging them in a database to be undone later, or bolting on a permissions system, all of which can be done by making a constructor wrapper and adding a few more lines of logic, and then privatizing the constructor to avoid it being called directly.
There are also cases where I've created a factory method which delegates to known children in order to provide a different implementation of a returned interface or abstract based on provided parameters. This has the added benefit of being able to hide the implementing classes - the Type class and IEnumerable interface make use of this pattern.
This pattern can be very useful, especially if you use a private constructor, and return an interface type from the Create, rather than the concrete type.
private ApplicationDbContext()
{
}
public static IApplicationDbContext Create()
{
return new ApplicationDbContext();
}
Now consumers of your class are prevented from depending on the concrete implementation - they can only rely on the abstraction.
Wrapping the constructor with static methods (creation methods) allows you to chose a specific name that conveys information. You can also create several methods with the same parameter signature such as CreateX(float f) and CreateY(float f), which you cannot do with constructors.
A situation where this is really useful is e.g. for creating structs that represent physical quantities that may have several units, such as time, length or weight. Here, you could use creation methods to force the programmer to always explicitly specify the unit instead of just passing a unit-less number to a single constructor (which assumes a certain unit, and getting it wrong might have huge consequences).
Example:
public struct Length
{
private const double MetersPerYard = 0.9144;
private double _meters;
private Length(double meters)
{
_meters = meters;
}
public static Length FromMeters(double meters)
{
return new Length(meters);
}
public static Length FromYards(double yards)
{
return new Length(yards*MetersPerYard);
}
public double Meters
{
get { return _meters; }
}
public double Yards
{
get { return _meters / MetersPerYard; }
}
}
Or take a look at TimeSpan and methods like FromMinutes, FromSeconds etc.
Is there an app or website where I can input parameter info (types and variable names), their defaults, and have it generate all the combinations of method overloads?
I have a class where the constructor can take in five parameters of different types. The parameters get mapped to properties, none of which have public setters. Each parameter has a default value.
I want my class to have overloaded constructors for all the various combinations of the parameters (ranging from no parameters to any and all combinations of the five parameters). To make it more confusing, one of the parameters can be passed in as a specific type or as a string, and I want the various combinations of overloads to take that into consideration.
Update:
I agree this design may not be the best. The class in question is one I'm using in a similar fashion to the PropertyMetadata class of WPF's DependencyProperty. A value is assigned for the property backing, and a new instance of the metadata class is passed in at that time. It's forcing my hand to create this cascading series of constructor overloads. Example:
private ModelProperty<UserModel, string> firstNameProperty =
RegisterProperty(p => p.FirstName, new ModelPropertyMetadata(**** lots of overloads here ****));
public string FirstName
{
get { return GetValue(firstNameProperty); }
set { SetValue(firstNameProperty, value); }
}
Maybe that's not the best design. I could possibly extend ModelPropertyMetadata to new classes which describe specific overloads, but that just seems like its pushing the problem somewhere else. Any thoughts on how to make this design better?
Take a look at optional parameters - these should help you avoid multiple overloads and still provide multiple ways to call a constructor. This is a .NET 4.0 feature.
Why not using optional parameters?
public MyClass(String myVar = null, Int32 v0 = 5, ...) { .. }
You can call the ctor this way:
new MyClass(v0: 10);
I don't know of one, but might I suggest you create a simple type that holds the parameters and has the defaulting logic and you pass that type into your class as what your suggesting will be difficult to maintain.
I have a some code that gets passed a class derived from a certain class. Let's call this a parameter class.
The code uses reflection to walk the class' members and analyze certain custom attributes given to them. Basically, it's a configurable parser which will analyze input according to the attributes and put what it found into the data members.
This is used in several places in our code. You specify the parameter class, putting in attributed data members, and pass this to the parser. Something like this:
public class MyFancyParameters : ParametersBase
{
[SomeAttribute(Name="blah", AnotherParam=true)]
public string Blah { get; set; }
// .. .more such stuff
}
var parameters = new MyFancyParameters();
Parser.Parse(input, parameters);
In many places there are similar groups of attributed data members that need to get parsed. So the parameter classes are, in some places, similar. That's redundant and that, of course, hurts. Whenever I need a change in such an area, I need to make that change in half a dozen places, all clones. It's just a matter of time when these parts will start drift apart.
However, the similarities cannot be grouped in acyclic graphs, so I can't use single inheritance to group them.
What I would do in C++ is to put these chunks of similar stuff into their own classes, just inherit a bunch of them that contain whatever I need, and be done. (I think that's referred to as mix-in inheritance.)
C#, however, doesn't have multiple inheritance. So I was thinking of putting these chunks into data members and change the parser to recurse into data members. But that would considerably complicate the parser.
What else is there?
Can you have your parser accept a collection of parameter classes instead of a single parameter class? Alternately, you could allow the parser to recurse into your parameter class and have it supply additional parameter classes as properties. Basically, every property of a ParametersBase derived class that inherits from type ParametersBase is recursed into and flattened into a single list of parameters.
Actually, I just saw that you already mentioned the recursive solution. I think this is probably your best bet and it's not too complex to support. You should be able to create a helper function for enumerating the parameter properties that makes a hierarchy look like a flat class.
Here's some code that would provided a 'flattened' view of your properties, if I understand your requirement correctly. You'll probably want to augment the production code with additional safeguards (such as keeping a stack of types to detect circular references.)
public class ParametersParser
{
public static IEnumerable<PropertyInfo> GetAllParameterProperties(Type parameterType)
{
foreach (var property in parameterType.GetProperties())
{
if (Attribute.IsDefined(property, typeof(SomeAttribute)))
yield return property;
if (typeof(ParametersBase).IsAssignableFrom(property.PropertyType))
{
foreach (var subProperty in GetAllParameterProperties(property.PropertyType))
yield return subProperty;
}
}
}
}
I am trying to create a web-based tool for my company that, in essence, uses geographic input to produce tabular results. Currently, three different business areas use my tool and receive three different kinds of output. Luckily, all of the outputs are based on the same idea of Master Table - Child Table, and they even share a common Master Table.
Unfortunately, in each case the related rows of the Child Table contain vastly different data. Because this is the only point of contention I extracted a FetchChildData method into a separate class called DetailFinder. As a result, my code looks like this:
DetailFinder DetailHandler;
if (ReportType == "Planning")
DetailHandler = new PlanningFinder();
else if (ReportType == "Operations")
DetailHandler = new OperationsFinder();
else if (ReportType == "Maintenance")
DetailHandler = new MaintenanceFinder();
DataTable ChildTable = DetailHandler.FetchChildData(Master);
Where PlanningFinder, OperationsFinder, and MaintenanceFinder are all subclasses of DetailFinder.
I have just been asked to add support for another business area and would hate to continue this if block trend. What I would prefer is to have a parse method that would look like this:
DetailFinder DetailHandler = DetailFinder.Parse(ReportType);
However, I am at a loss as to how to have DetailFinder know what subclass handles each string, or even what subclasses exist without just shifting the if block to the Parse method. Is there a way for subclasses to register themselves with the abstract DetailFinder?
You could use an IoC container, many of them allows you to register multiple services with different names or policies.
For instance, with a hypothetical IoC container you could do this:
IoC.Register<DetailHandler, PlanningFinder>("Planning");
IoC.Register<DetailHandler, OperationsFinder>("Operations");
...
and then:
DetailHandler handler = IoC.Resolve<DetailHandler>("Planning");
some variations on this theme.
You can look at the following IoC implementations:
AutoFac
Unity
Castle Windsor
You might want to use a map of types to creational methods:
public class DetailFinder
{
private static Dictionary<string,Func<DetailFinder>> Creators;
static DetailFinder()
{
Creators = new Dictionary<string,Func<DetailFinder>>();
Creators.Add( "Planning", CreatePlanningFinder );
Creators.Add( "Operations", CreateOperationsFinder );
...
}
public static DetailFinder Create( string type )
{
return Creators[type].Invoke();
}
private static DetailFinder CreatePlanningFinder()
{
return new PlanningFinder();
}
private static DetailFinder CreateOperationsFinder()
{
return new OperationsFinder();
}
...
}
Used as:
DetailFinder detailHandler = DetailFinder.Create( ReportType );
I'm not sure this is much better than your if statement, but it does make it trivially easy to both read and extend. Simply add a creational method and an entry in the Creators map.
Another alternative would be to store a map of report types and finder types, then use Activator.CreateInstance on the type if you are always simply going to invoke the constructor. The factory method detail above would probably be more appropriate if there were more complexity in the creation of the object.
public class DetailFinder
{
private static Dictionary<string,Type> Creators;
static DetailFinder()
{
Creators = new Dictionary<string,Type>();
Creators.Add( "Planning", typeof(PlanningFinder) );
...
}
public static DetailFinder Create( string type )
{
Type t = Creators[type];
return Activator.CreateInstance(t) as DetailFinder;
}
}
As long as the big if block or switch statement or whatever it is appears in only one place, it isn't bad for maintainability, so don't worry about it for that reason.
However, when it comes to extensibility, things are different. If you truly want new DetailFinders to be able to register themselves, you may want to take a look at the Managed Extensibility Framework which essentially allows you to drop new assemblies into an 'add-ins' folder or similar, and the core application will then automatically pick up the new DetailFinders.
However, I'm not sure that this is the amount of extensibility you really need.
To avoid an ever growing if..else block you could switch it round so the individal finders register which type they handle with the factory class.
The factory class on initialisation will need to discover all the possible finders and store them in a hashmap (dictionary). This could be done by reflection and/or using the managed extensibility framework as Mark Seemann suggests.
However - be wary of making this overly complex. Prefer to do the simplest thing that could possibly work now with a view to refectoring when you need it. Don't go and build a complex self-configuring framework if you'll only ever need one more finder type ;)
You can use the reflection.
There is a sample code for Parse method of DetailFinder (remember to add error checking to that code):
public DetailFinder Parse(ReportType reportType)
{
string detailFinderClassName = GetDetailFinderClassNameByReportType(reportType);
return Activator.CreateInstance(Type.GetType(detailFinderClassName)) as DetailFinder;
}
Method GetDetailFinderClassNameByReportType can get a class name from a database, from a configuration file etc.
I think information about "Plugin" pattern will be useful in your case: P of EAA: Plugin
Like Mark said, a big if/switch block isn't bad since it will all be in one place (all of computer science is basically about getting similarity in some kind of space).
That said, I would probably just use polymorphism (thus making the type system work for me). Have each report implement a FindDetails method (I'd have them inherit from a Report abstract class) since you're going to end with several kinds of detail finders anyway. This also simulates pattern matching and algebraic datatypes from functional languages.