I have a dictionary that contains classes. However, I have a lot of classes to add to the dictionary and I would like to eliminate the long list of adds, because it's starting to look messy. I was thinking of having all the data in a file and loading it to add to the dictionary, but then I realized that every time I wanted to create and add a new class, I would have to modify the file. I would prefer to have to include something in my newly created class that would automatically add it to the dictionary. I'm not even sure this is possible, so I would appreciate any help.
Try to use reflection to dynamically locate all the required classes. Create an instance of Assembly where your classes are defined and try to filter them out. An example below shows how to locate all the classes whose name ends with Task.
var assembly = Assembly.GetExecutingAssembly();
var taskTypes = assembly.GetTypes()
.Where(t => t.Name.EndsWith("Task") && t.IsClass);
Dictionary<string, object> instances =
new Dictionary<string, object>(taskTypes.Count());
foreach (Type classType in taskTypes)
{
object instance = Activator.CreateInstance(classType);
instances.Add(classType.Name, instance);
Console.WriteLine("Registered key {0} with object of type {1})",
classType.Name,
instance);
}
I've used Activator.CreateInstance method to create instances of your classes, but this might not be possible in your case depending on whether they have parameterless contructors etc.
Another option might be to use one of the available IoC containers like autofac but I need more details on your problem before I can give a proper advice on this.
Make the dictionary a static field of some class, or make the "add class to dictionary" a static method.
Then, you can use a static constructor to add each class to the dictionary:
class ClassDict {
...
public static void AddClass(Type t) {
...
}
}
class Foo {
static Foo() {
ClassDict.AddClass(typeof(Foo));
}
}
Related
I want to create my own Boolean operation on an element to pass in as a FilterRule. The ElementPasses member description states:
Derived classes override this method to implement the test that determines whether the given element passes this rule or not.
I have tried to create my own derived class but I can't figure out how to implement it. I would think an interface would be available but I can't find anything. Annoyingly, I remember seeing an example of this but I can't seem to find anything.
This fails with: Static class 'ParameterDefinitionExists' cannot derive from type 'FilterRule'. Static classes must derive from object.
static public class ParameterDefinitionExists : FilterRule
{
public static bool ElementPasses(Element element)
{
return true;
}
}
And this fails with:'FilterRule' does not contain a constructor that takes 0 arguments
static public class ParameterDefinitionExists : FilterRule
{
new public bool ElementPasses(Element element)
{
return true;
}
}
What constructor arguments does it take?
There may be another way to go about it but I can't anything for FilterRules. I'm trying to define and refine a trigger in an updater but maybe I should query the element after it is passed in to the command. I imagine catching it with a filter rule is more efficient.
You have to use one of the Revit API classes derived from FilterRule:
Inheritance Hierarchy
System Object
Autodesk.Revit.DB FilterRule
Autodesk.Revit.DB FilterCategoryRule
Autodesk.Revit.DB FilterInverseRule
Autodesk.Revit.DB FilterValueRule
Autodesk.Revit.DB SharedParameterApplicableRule
Cf. http://www.revitapidocs.com/2017/a8f202ca-3c88-ecc4-fa93-549b26a412d7.htm
The Building Coder provides several examples creating and using parameter filters:
http://thebuildingcoder.typepad.com/blog/2010/08/elementparameterfilter-with-a-shared-parameter.html
Here is the entire topic group on filtering.
I want to create a code in C# for Private constructor.
I want that it should allow only one object to be created but when I try to create more than one a message showing no more object can be created should be shown.
I don't want to use static constructor in this code.
How do I do that in C#?
You may use static counter or flag that will be set in your private counstructor to show that at least one instance were created.
But first of all, I suggest you to pay attention to Singleton pattern.
Simple, this is the classic singleton pattern:
public class MyClass
{
public static MyClass Instance;
private MyClass()
{
if (Instance != null)
throw new InvalidOperationException("no more object can be created");
// do other constructor logic
Instance = this;
}
}
Please note that synchronization has been left out. This code need synchronization for thread safe purpose.
Is it possible to convert ExpandoObject to anonymously typed object?
Currently I have HtmlHelper extension that can take HTML attributes as a parameter. The problem is that my extension also needs to add some HTML attributes so I've use ExpandoObject to merge my attributes and attributes that user passes to the function using htmlAttributes parameter. Now I need to pass merged HTML attributes to original HtmlHelper function, and when I send ExpandoObject, nothing happens. So I guess that I need to convert ExpandoObject to anonymously typed object or something similar - any suggestions are welcome.
I don't think that you need to deal with expandos to achieve your goal:
public static class HtmlExtensions
{
public static IHtmlString MyHelper(this HtmlHelper htmlHelper, object htmlAttributes)
{
var builder = new TagBuilder("div");
// define the custom attributes. Of course this dictionary
// could be dynamically built at runtime instead of statically
// initialized as in my example:
builder.MergeAttribute("data-myattribute1", "value1");
builder.MergeAttribute("data-myattribute2", "value2");
// now merge them with the user attributes
// (pass "true" if you want to overwrite existing attributes):
builder.MergeAttributes(new RouteValueDictionary(htmlAttributes), false);
builder.SetInnerText("hello world");
return new HtmlString(builder.ToString());
}
}
and if you wanted to call some of the existing helpers, then a simple foreach loop could do the job:
public static class HtmlExtensions
{
public static IHtmlString MyHelper(this HtmlHelper htmlHelper, object htmlAttributes)
{
// define the custom attributes. Of course this dictionary
// could be dynamically built at runtime instead of statically
// initialized as in my example:
var myAttributes = new Dictionary<string, object>
{
{ "data-myattribute1", "value1" },
{ "data-myattribute2", "value2" }
};
var attributes = new RouteValueDictionary(htmlAttributes);
// now merge them with the user attributes
foreach (var item in attributes)
{
// remove this test if you want to overwrite existing keys
if (!myAttributes.ContainsKey(item.Key))
{
myAttributes[item.Key] = item.Value;
}
}
return htmlHelper.ActionLink("click me", "someaction", null, myAttributes);
}
}
Is it possible to convert ExpandoObject to anonymously typed object?
Only if you generate the anonymous type yourself at execution time.
Anonymous types are normally created by the compiler, at compile-time, and baked into your assembly like any other type. They're not dynamic in any sense. So, you'd have to use CodeDOM or something similar to generate the same kind of code that's used for anonymous type... that's not going to be fun.
I think it's rather more likely that someone else will have created some MVC helper classes which know about ExpandoObject (or can just work with IDictionary<string, object>).
I want a magic to happen like that...
class SomeClass {}
public static void main()
MagicFunctionOrMacrosOrSomethingThatGetTypeOf("SomeClass") some_var = null;<br />
}
Maybe it's crazy, but is it possible?
I need it to avoid crazy large switch case, because has a lot of classes, but at certain point of code is unable to tell what of the classes to create.
Let's have an example:
I have base class:
class baseCLASS {}
have a lot of child classes:
class class1 : baseCLASS {}
class class2 : baseCLASS {}
...
class classn : baseCLASS {}
have some flag that comes from outside to events handler:
string class_name; //actually i use int flag that should have connected with string names in dictionary.
have forced to make this:
switch(class_name)
case "class1":
class1 some_class = new class1();
some_class.RunHandler();
break;
case "class2":
class2 some_class = new class2();
some_class.RunHandler();
break;
case "classn":
classn some_class = new classn();
some_class.RunHandler();
break;
}
I want to replace that large switch statement by something like this:
MagicFunctionOrMacrosOrSomethingThatGetTypeOf(class_name) some_var = null;
... some initialization actions with some_var
some_var.Build();
some_var.RunHandler();
oh my...
You have two problems:
Given user input, you want to instantiate an object of a varying class. For this, you want a mapping between user input and .NET type name. For the first: you can use a convention -- ensure that the type name matches the input; or you can use a Dictionary<string,type>, and populate it; or you can attach an attribute to each class, showing which "verb" it handles. Once you've done that, you can use Activator.CreateInstance to (at runtime) create an instance of your unknown class. This returns object.
Calling methods on the unknown object. Either define a base class or common interface for the classes (e.g. IRunnable or something), or use dynamic, which gives you duck typing.
There are a lot of workarounds for the missing support of enumerations in the Entity Framework 4.0. From all of them I like this one at most:
http://blogs.msdn.com/b/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx?PageIndex=2#comments
This workaround allows you to use enums in your LINQ queries which is what i exactly need. However, I have a problem with this workaround. I get for every complex type I'm using a new partial autogenerated class.Therefore the code does not compile any more because I already have a wrapper class with this name in the same namespace which converts betwen the backed integer in the database and the enum in my POCO classes. If I make my wrapper a partial class, the code still does not compile as it now contains two properties with the same name "Value". The only possibility is to remove the Value property by hand everytime I generate the POCO classes because the DB model changed (which during the development phase happens very often).
Do you know how to prevent a partial class to be generated out of complex property everytime the EF model changes?
Can you recommend me some other workarounds supporting enumerations in LINQ queries?
That workaround is based on the fact that you are writing your POCO classes yourselves = no autogeneration. If you want to use it with autogeneration you must heavily modify T4 template itself.
Other workaround is wrapping enum conversion to custom extension methods.
public static IQueryable<MyEntity> FilterByMyEnum(this IQueryable<MyEntity> query, MyEnum enumValue)
{
int val = (int)enumValue;
return query.Where(e => e.MyEnumValue == val);
}
You will then call just:
var data = context.MyEntitites.FilterByMyEnum(MyEnum.SomeValue).ToList();
I am using an approach based on the one described in your link without any modifications of the T4 templates. The contents of my partial wrapper classes are as follows:
public partial class PriorityWrapper
{
public Priority EnumValue
{
get
{
return (Priority)Value;
}
set
{
Value = (int)value;
}
}
public static implicit operator PriorityWrapper(Priority value)
{
return new PriorityWrapper { EnumValue = value };
}
public static implicit operator Priority(PriorityWrapper value)
{
if (value == null)
return Priority.High;
else
return value.EnumValue;
}
}
I've only changed that instead of a back store variable with enum value I am using the autogenerated int typed Value property. Consequently Value can be an auto-implemented property and EnumValue property needs to do the conversion in getter and setter methods.