Is it possible to create classes within a template? Something like...
#{
public class MyClass {
public MyClass() {
Three = new List<string>();
}
public string One { get; set; }
public int Two { get; set; }
public List<string> Three { get; set; }
}
}
Currently I get "Unable to compile template. Check the Errors list for details." when I try to do this. I would like to take XML content and use XmlSerializer to create an instance of MyClass within the template. I can't do the deserialization before hand and shove it into the model because the classes could vary depending on the template.
Yes, this is completely possible. Use the #functions keyword:
#functions {
public class MyClass {
public MyClass() {
Three = new List<string>();
}
public string One { get; set; }
public int Two { get; set; }
public List<string> Three { get; set; }
}
}
I'll post my response from the CodePlex Discussion here:
I'm not sure that is currently possible. When you use codeblocks (#{ }), you're actually writing code within a method, e.g. your above code would do something like:
public void Execute()
{
this.Clear();
public class MyClass {
public MyClass() {
Three = new List<string>();
}
public string One { get; set; }
public int Two { get; set; }
public List<string> Three { get; set;}
}
}
...which of course, is not valid C#. The other problem you will face, is that to use xml serialisation/deserialisation, the type must be known, but if you are defining your type within the template itself, how could you deserialise it in the first place?
What you could do, is use a custom base template:
public class CustomTemplateBase<T> : TemplateBase<T>
{
public dynamic Instance { get; set; }
public dynamic CreateInstance(string typeName)
{
Type type = Type.GetType(typeName);
// You'd to your deserialisation here, I'm going to
// just cheat and return a new instance.
return Activator.CreateInstance(type);
}
}
Using a dynamic property and dynamic return type, we've defined a method that will let us create an instance (through activation or deserialisation, etc.) and call member access on it. To use that in a template, you could then do:
#{
Instance = CreateInstance("ConsoleApplication1.MyClass, ConsoleApplication1");
Instance.One = "Hello World";
}
<h1>#Instance.One</h1>
Where "MyClass" is a defined somewhere in my application. The important thing is, I'm creating an instance per template.
I would suggest using a specific ViewModel class, which could have a dynamic property (ExpandoObject) allowing you to populate it with any custom data structure as needed while still communicating strongly typed for whatever else your view might need.
This also keeps your view models separate from the views themselves, which is good practice (html and code don't mix too well where readability is a concern).
Related
I have a bunch of classes that formulate various variations of items. I currently have a class like this:
public class Item {
public ItemFile file { get; set;}
public ItemCalendar calendar { get; set;}
public ItemWebsite website { get; set;}
}
ItemFile etc are classes made using Entity Framework and map to the database tables that provide the information relating to that type of item. The item class only has one of the internal properties actually instantiated.
I can see the number of items growing to around 25 or more. I don't feel right making the view model containing 25 properties where 24 of them are null with only one being not null.
I want something that can work with entity framework and return a class that can return only it's actual type. Therefore if I ask for the variation of the item I would get back ItemFile for files and ItemCalendar for calendars.
I've tried something like this:
public class Item
{
public ItemBase item { get; set; }
}
public class ItemBase
{
public Type typeName { get; set; }
public object ItemInstance { get; set; }
public typeName GetInstance()
{
return Convert.ChangeType(ItemInstance, typeName);
}
}
But then I don't know how to return ItemFile as public typeName is an error.
I then tried:
public class Item
{
public ItemBase<ItemFile> item { get; set; }
}
public class ItemBase<T>
{
public T ItemInstance { get; set; }
}
But to get that to work, I had to hardcore FileItem in the <> on the item class which goes back into knowing the type before hand.
Is there anyway to get this to work? Bonus points if it can work with entity framework as I'm pulling back the classes from there. Worst comes to worst if it doesn't work entity framework wise is I can pull it all and then convert it into the form that answers the question.
If the title of the question is wrong, feel free to edit. I wasn't sure how to ask.
tl;dr version: I want to be able to return multiple types of classes from a function using a type that is passed in not using <>.
Edit 1:
I forgot to show my inheritence example. I've tried this but also got stuck with something similar to the above.
public class ItemBase
{
public Type typeName { get; set; }
public object ItemInstance { get; set; }
public typeName GetInstance()
{
return Convert.ChangeType(ItemInstance, typeName);
}
}
public class ItemFile : ItemBase
{
public String FileName { get; set; }
}
public class Test
{
public void testFunction()
{
//Made this just so the compiler didn't complain.
ItemFile testFile = new ItemFile();
//I can use a function to get the item base.
ItemBase baseItem = testFile;
//How do I do this? Use a function to get the ItemFile from the instance.
ItemFile finalItem = baseItem.GetInstance();
}
}
I want to be able to return multiple types of classes from a function using a type that is passed in not using <>.
<> (generics) are the mechanism by which a function can explicitly return more than one type. Without generics the function returns whatever type it says it returns.
object SomeFunction() // Returns an object
ItemBase SomeOtherFunction () // returns ItemBase
In the above examples, SomeFunction can still return any type (because all types inherit from object.) But it won't be explicit. All you know for sure is that it's an object.
Similarly, SomeOtherFunction can return an ItemBase or any class that inherits from ItemBase. But that's all you know about it.
Ideally you don't want to have functions returning one type (like object or ItemBase) and then cast the result of the function to another more specific type. The function should return what you want, and you should want what the function returns. Generics help with that. For example:
public TItem Instance<TItem>() where TItem : ItemBase
allows a function to return a specified type as long as it is an ItemBase or inherits from one.
This last comment is going to seem odd or useless but it's the truth. If you find yourself in a scenario where the above rules don't work and you need to be able to do something that you can't do or shouldn't do, go back and rethink why you're trying to do that. That's where the real problem is.
That means you probably need to go back a step and get yourself out of the situation where you're trying to work against the language. What are you trying to accomplish and how can you do it in a way that works with the language, not against it?
I believe this is about as close as you're going to get.
using System;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
EFTypeData itemData = GetItemData();
var asmName = Assembly.GetExecutingAssembly().GetName().Name;
var type = Type.GetType($"ConsoleApplication1.{itemData.TypeName}, {asmName}");
var instance = Activator.CreateInstance(type);
var item = new Item<Object>()
{
ItemBase = instance
};
}
private static EFTypeData GetItemData()
{
return new EFTypeData() { TypeName = "ItemFile" };
}
}
class EFTypeData
{
public string TypeName { get; set; }
}
class Item<T> where T: class
{
public T ItemBase { get; set; }
}
class ItemFile
{
public string FileName { get; set; }
}
}
This will, given a string "ItemFile", create an instance and assign it to Item. If you run this and inspect item, you have
The big caveat to this is that at compile-time, all you have is an Object as your ItemBase. And without hard-coding your Type (i.e. var item = new Item<ItemFile>();), you're never going to know more.
That said, with this method you are perfectly clear to iterate over fields and such using Reflection. But this is a limitation of this level of run-time object manipulation.
I need to implement few custom properties in PropertyGrid at runtime. After reading dozens of articles, a simple & elegant solution I found is by #Simon Mourier in another stackoverflow thread:
Custom, Complicated, Dynamic Reflection Solution - C#
However, this solution add only expandable properties.
I need also root properties to be added dynamically, like "Name" in picture above.
This is the Holder class:
public class MyHolder
{
public MyHolder()
{
Objects = new List<object>();
}
public string Name { get; set; } // this is not dynamic
[TypeConverter(typeof(MyCollectionConverter))]
public List<object> Objects { get; private set; }
}
How can I modifpublic class MyHolder
{
public MyHolder()
{
Objects = new List<object>();
}
public string Name { get; set; }
[TypeConverter(typeof(MyCollectionConverter))]
public List<object> Objects { get; private set; }
}
I tried to derive the Holder class from CollectionBase,ICustomTypeDescriptor like in this old article
http://www.codeproject.com/Articles/9280/Add-Remove-Items-to-from-PropertyGrid-at-Runtime
But obvious, mixed things are not working.
How can I make root properties (like "Name") of Holder class to be dynamic, to be add at runtime too?
Thanks very much in advance,
I wrote the following console app to test static properties:
using System;
namespace StaticPropertyTest
{
public abstract class BaseClass
{
public static int MyProperty { get; set; }
}
public class DerivedAlpha : BaseClass
{
}
public class DerivedBeta : BaseClass
{
}
class Program
{
static void Main(string[] args)
{
DerivedBeta.MyProperty = 7;
Console.WriteLine(DerivedAlpha.MyProperty); // outputs 7
}
}
}
As this console app demonstrates, the MyProperty property exists once for all instances of BaseClass. Is there a pattern to use which would allow me to define a static property which will have allocated storage for each sub-class type?
Given the above example, I would like all instances of DerivedAlpha to share the same static property, and all instances of DerivedBeta to share another instance of the static property.
Why am I trying to do this?
I am lazily initializing a collection of class property names with certain attributes (via reflection). The property names will be identical for each derived class instance, so it seems wasteful to store this in each class instance. I can't make it static in the base class, because different sub-classes will have different properties.
I don't want to replicate the code which populates the collection (via reflection) in each derived class. I know that one possible solution is to define the method to populate the collection in the base class, and call it from each derived class, but this is not the most elegant solution.
Update - Example of what I'm doing
At Jon's request, here's an example of what I'm trying to do. Basically, I can optionally decorate properties in my classes with the [SalesRelationship(SalesRelationshipRule.DoNotInclude)] attribute (there are other attributes, this is just a simplified example).
public class BaseEntity
{
// I want this property to be static but exist once per derived class.
public List<string> PropertiesWithDoNotInclude { get; set; }
public BaseEntity()
{
// Code here will populate PropertiesWithDoNotInclude with
// all properties in class marked with
// SalesRelationshipRule.DoNotInclude.
//
// I want this code to populate this property to run once per
// derived class type, and be stored statically but per class type.
}
}
public class FooEntity : BaseEntity
{
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_A { get; set; }
public int? Property_B { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_C { get; set; }
}
public class BarEntity : BaseEntity
{
public int? Property_D { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_E { get; set; }
public int? Property_F { get; set; }
}
Desired end result
Accessing FooEntity.PropertiesWithDoNotInclude returns a List<string> of:
{
"Property_A",
"Property_C"
}
Accessing BarEntity.PropertiesWithDoNotInclude returns a List<string> of:
{
"Property_E"
}
Two possible approaches:
Use attributes; decorate each subclass with an attribute, e.g.
[MyProperty(5)]
public class DerivedAlpha
{
}
[MyProperty(10)]
public class DerivedBeta
{
}
That only works when they're effectively constants, of course.
Use a dictionary:
var properties = new Dictionary<Type, int>
{
{ typeof(DerivedAlpha), 5) },
{ typeof(DerivedBeta), 10) },
};
EDIT: Now that we have more context, Ben's answer is a really good one, using the way that generics work in C#. It's like the dictionary example, but with laziness, thread-safety and simple global access all built in.
Jon has a good solution as usual, although I don't see what good attributes do here, since they have to be explicitly added to every subtype and they don't act like properties.
The Dictionary approach can definitely work. Here's another way to do that, which explicitly declares that there will be one variable per subclass of BaseEntity:
class FilteredProperties<T> where T : BaseEntity
{
static public List<string> Values { get; private set; }
// or static public readonly List<string> Values = new List<string>();
static FilteredProperties()
{
// logic to populate the list goes here
}
}
The drawback of this is that it's rather difficult to pair with a GetType() call such as you might use in methods of BaseEntity. A Dictionary, or wrapper thereto which implements lazy population, is better for that usage.
I just recently needed this same thing and came across this question. I think Jon's and Fried's ideas to use a Dictionary are on the right track but don't quite hit what I was looking for so I thought I'd show my own complete and very easy to extend implementation.
public class TypeStaticProperty<T>
{
T _defaultValue;
Dictionary<Type, T> _values = new Dictionary<Type, T>();
public TypeStaticProperty(T defalutValue = default)
{
_defaultValue = defalutValue;
}
public T Get(object caller)
{
lock (_values)
{
if (_values.TryGetValue(caller?.GetType(), out T val))
return val;
else
return _defaultValue;
}
}
public void Set(object caller, T val)
{
lock (_values)
_values[caller?.GetType()] = val;
}
}
And to demonstrate:
class TestBaseClass
{
static TypeStaticProperty<int> _property = new TypeStaticProperty<int>();
public int Property
{
get => _property.Get(this);
set => _property.Set(this, value);
}
}
class TestClass1 : TestBaseClass
{
}
class TestClass2 : TestBaseClass
{
}
class Program
{
static void Main(string[] args)
{
TestClass1 test1a = new TestClass1();
TestClass1 test1b = new TestClass1();
test1a.Property = 1;
test1b.Property = 2;
TestClass2 test2a = new TestClass2();
TestClass2 test2b = new TestClass2();
test2a.Property = 3;
test2b.Property = 4;
Console.WriteLine($"test1a.Property = {test1a.Property}");
Console.WriteLine($"test1b.Property = {test1b.Property}");
Console.WriteLine($"test2a.Property = {test2a.Property}");
Console.WriteLine($"test2b.Property = {test2b.Property}");
}
}
Output:
test1a.Property = 2
test1b.Property = 2
test2a.Property = 4
test2b.Property = 4
So while you still need a class instance to access and set the property, the value will always be the same across all instances of that precise type. (This includes generics too; Foo<int> will be seen as a different type than Foo<string>). This has the huge advantage over Fried's example in that you don't need to know at compile time the precise type whose "static" value you're looking for when accessing or setting.
PS - For full disclosure, this was heavily inspired by the WPF source code, which uses a very similar pattern for DependencyProperty's and all kinds of other internal bells and whistles designed to improve performance and reduce memory footprint.
I'm currently trying to figure out how to have a wrapper class expose the properties of whatever it is wrapping without having to manually set them one by one in the wrapper class. I've been trying to figure out if this is even a good design choice or if I'm totally misguided and going off into a very bad placeā¢ by doing this.
I also already have my wrapper class inheriting something...
Example code below (fake objects so don't read into them please):
public class Car {
public String Name { get; set; }
public String Status { get; set; }
public String Type { get; set; }
public Car(takes params) {
// makes car!
}
}
public class CarWrapper : OtherAutomotiveRelatedThing {
public Car car;
public CarWrapper(Car c) {
car = c;
}
}
public class OtherAutomotiveRelatedThing {
public String Property1 { get; protected set; }
public String Property2 { get; protected set; }
}
I'm using inheritance on the wrapper object because I can not modify the base Car class and it needs the properties of other automotive thing. Multiple other classes inherit from OtherAutomotiveRelatedThing as well.
I return a list of the CarWrapper objects as Json (because I'm building a web app) and the wrapper object is causing problems for me. When cast/converted to Json the CarWrapper objects in the list all contain another nested object - the Car object and the framework I'm using can't get at its properties to do what it needs.
Is there a way to expose the wrapped Car object's properties at the "top level" of the CarWrapper without doing the following:
public class CarWrapper : OtherAutomotiveRelatedThing {
public Car car;
public String Name { get; private set; }
public String Status { get; private set; }
public String Type { get; private set; }
public CarWrapper(Car c) {
car = c;
this.Name = c.Name;
this.Status = c.Status;
this.Type = c.Type;
}
}
Please let me know if I'm not being clear, if you have any questions, or need/want more info.
Thanks!
For me it looks like you want prototype-style programming like in JavaScript, which is not they use in OOP.
Maybe it's good start to think of it as "If I have two different car wrappers (with differnt properties set), how should I pass any of them a method?" or "Can I have a single wrapper which wraps Car and Animal", and "How to expose public property which has the same name but different meaning for Car and Animal, like skin color?" etc
Answers may help you identify if you need say interfaces, or wrappers which expose public objects, or pure encapsulation, or changing language to say JavaScript.
I have a class called Question that has a property called Type. Based on this type, I want to render the question to html in a specific way (multiple choice = radio buttons, multiple answer = checkboxes, etc...). I started out with a single RenderHtml method that called sub-methods depending on the question type, but I'm thinking separating out the rendering logic into individual classes that implement an interface might be better. However, as this class is persisted to the database using NHibernate and the interface implementation is dependent on a property, I'm not sure how best to layout the class.
The class in question:
public class Question
{
public Guid ID { get; set; }
public int Number { get; set; }
public QuestionType Type { get; set; }
public string Content { get; set; }
public Section Section { get; set; }
public IList<Answer> Answers { get; set; }
}
Based on the QuestionType enum property, I'd like to render the following (just an example):
<div>[Content]</div>
<div>
<input type="[Depends on QuestionType property]" /> [Answer Value]
<input type="[Depends on QuestionType property]" /> [Answer Value]
<input type="[Depends on QuestionType property]" /> [Answer Value]
...
</div>
Currently, I have one big switch statement in a function called RenderHtml() that does the dirty work, but I'd like to move it to something cleaner. I'm just not sure how.
Any thoughts?
EDIT: Thanks to everyone for the answers!
I ended up going with the strategy pattern using the following interface:
public interface IQuestionRenderer
{
string RenderHtml(Question question);
}
And the following implementation:
public class MultipleChoiceQuestionRenderer : IQuestionRenderer
{
#region IQuestionRenderer Members
public string RenderHtml(Question question)
{
var wrapper = new HtmlGenericControl("div");
wrapper.ID = question.ID.ToString();
wrapper.Attributes.Add("class", "question-wrapper");
var content = new HtmlGenericControl("div");
content.Attributes.Add("class", "question-content");
content.InnerHtml = question.Content;
wrapper.Controls.Add(content);
var answers = new HtmlGenericControl("div");
answers.Attributes.Add("class", "question-answers");
wrapper.Controls.Add(answers);
foreach (var answer in question.Answers)
{
var answerLabel = new HtmlGenericControl("label");
answerLabel.Attributes.Add("for", answer.ID.ToString());
answers.Controls.Add(answerLabel);
var answerTag = new HtmlInputRadioButton();
answerTag.ID = answer.ID.ToString();
answerTag.Name = question.ID.ToString();
answer.Value = answer.ID.ToString();
answerLabel.Controls.Add(answerTag);
var answerValue = new HtmlGenericControl();
answerValue.InnerHtml = answer.Value + "<br/>";
answerLabel.Controls.Add(answerValue);
}
var stringWriter = new StringWriter();
var htmlWriter = new HtmlTextWriter(stringWriter);
wrapper.RenderControl(htmlWriter);
return stringWriter.ToString();
}
#endregion
}
The modified Question class uses an internal dictionary like so:
public class Question
{
private Dictionary<QuestionType, IQuestionRenderer> _renderers = new Dictionary<QuestionType, IQuestionRenderer>
{
{ QuestionType.MultipleChoice, new MultipleChoiceQuestionRenderer() }
};
public Guid ID { get; set; }
public int Number { get; set; }
public QuestionType Type { get; set; }
public string Content { get; set; }
public Section Section { get; set; }
public IList<Answer> Answers { get; set; }
public string RenderHtml()
{
var renderer = _renderers[Type];
return renderer.RenderHtml(this);
}
}
Looks pretty clean to me. :)
Generally speaking, whenever you see switches on a Type or Enum, it means you can substitute in objects as the "Type" - said differently, a case for polymorphism.
What this means practically is that you'll create a different class for each Question type and override the RenderHTML() function. Each Question object will be responsible for knowing what input type it ought to output.
The benefits are that you remove the switch statement as well as produce good OO based code. The draw backs are that you add a class for every Question type (in this case minimal impact.)
You can for example use the strategy pattern:
Have all your HTML renderers implement a common interface, for example IQuestionRenderer, with a method name Render(Question).
Have an instance of Dictionary<QuestionType, IQuestionRenderer> in your application. Populate it at initialization time, perhaps based on a configuration file.
For a given instance of a question, do: renderers[question.Type].Render(question)
Or, you could have methods named RenderXXX where XXX is the question type, and invoke them by using reflection.
This is a classic case for using object inheritance to achieve what you want. Anytime you see a big switch statement switching on the type of an object, you should consider some form of subclassing.
I see two approaches, depending on how "common" these question types really are and whether rendering is the only difference between them:
Option 1 - Subclass the Question class
public class Question
{
public Guid ID { get; set; }
public int Number { get; set; }
public string Content { get; set; }
public Section Section { get; set; }
public IList<Answer> Answers { get; set; }
public virtual string RenderHtml();
}
public class MultipleChoiceQuestion
{
public string RenderHtml() {
// render a radio button
}
}
public class MultipleAnswerQuestion
{
public string RenderHtml() {
// render a radio button
}
}
Option 2 - Create a render interface, and make that a property on your question class
public class Question
{
public Guid ID { get; set; }
public int Number { get; set; }
public string Content { get; set; }
public Section Section { get; set; }
public IList<Answer> Answers { get; set; }
public IRenderer Renderer { get; private set; }
}
public interface IRenderer {
void RenderHtml(Question q);
}
public class MultipleChoiceRenderer : IRenderer
{
public string RenderHtml(Question q) {
// render a radio button
}
}
public class MultipleAnswerRenderer: IRenderer
{
public string RenderHtml(Question q) {
// render checkboxes
}
}
In this case, you would instantiate the renderer in your constructor based on the question type.
Option 1 is probably preferable if question types differ in more ways than rendering. If rendering is the only difference, consider Option 2.
It's a good idea to separate the rendering logic into its own class. You don't want rendering logic embedded into the business logic of your application.
I would create a class called QuestionRenderer that takes in a Question, reads its type, and outputs rendering accordingly. If you're using ASP.NET it could output webcontrols, or you could do a server control that outputs HTML.
Why not have a QuestionRenderer class (actually, it will be a control) which exposes a Question as a property which you can set.
In the render method, you can decide what to render based on the question type.
I don't like the idea of rendering details being in the same class as the data.
So, one option would be to have your rendering method simply generate one of a set of user controls that handled the actual HTML rendering.
Another would be to have a separate class QuestionRenderer which would have the various subclasses for question types (each of which would render the correct HTML).
I think what you want is an IUserType that convert the property from the hibernate mapping to the correct control type via some Question factory.
An example of the use of an IuserType can be found here:
NHibernate IUserType
in the example it converts a blob to an image for use on the client side but with the same idea you can make your page created with the QuestionType.
You could use the strategy pattern (Wikipedia) and a factory in combination.
public class Question
{
public Guid ID { get; set; }
public int Number { get; set; }
public QuestionType Type { get; set; }
public string Content { get; set; }
public Section Section { get; set; }
public IList<Answer> Answers { get; set; }
private IQuestionRenderer renderer;
public RenderHtml()
{
if (renderer == null)
{
QuestionRendererFactory.GetRenderer(Type);
}
renderer.Render(this);
}
}
interface IQuestionRenderer
{
public Render(Question question);
}
public QuestionRendererA : IQuestionRenderer
{
public Render(Question question)
{
// Render code for question type A
}
}
public QuestionRendererB : IQuestionRenderer
{
public Render(Question question)
{
// Render code for question type B
}
}
public QuestionRendererFactory
{
public static IQuestionRenderer GetRenderer(QuestionType type)
{
// Create right renderer for question type
}
}
Only the public properties need to be included in NHibernate.
The rendering is definitely a UI concern, so I'd separate that from the Question class and add a factory to isolate the switching logic (the QuestionControl base class inherits from WebControl and would contain the majority of the rendering logic):
RadioButtonQuestionControl: QuestionControl {
// Contains radio-button rendering logic
}
CheckboxListQuestionControl: QuestionControl {
// Contains checkbox list rendering logic
}
QuestionControlFactory {
public QuestionControl CreateQuestionControl(Question question) {
// Switches on Question.Type to produce the correct control
}
}
Usage:
public void Page_Load(object sender, EventArgs args) {
List<Question> questions = this.repository.GetQuestions();
foreach(Question question in Questions) {
this.Controls.Add(QuestionControlFactory.CreateQuestionControl(question));
// ... Additional wiring etc.
}
}
Stating the obvious: You could probably use a factory method to get the instance of the required rendered class and call render on that to get the required output.
The approach I would take is to create a separate Control (or a HtmlHelper method if you're in MVC) for each visual style you would like your questions to be rendered using. This separates the concerns of representing the question as an object and representing it visually neatly.
Then you can use a master Control (or method) to choose the correct rendering method based on the type of the Question instance presented to it.