I have created a custom selector attribute, that filters what customers will appear in the popup box based on the user's ID.
But I have run into the problem that I can't seem to customize it like a normal selector
ie:
[PXSelector(typeof(Search2<InventoryItem.inventoryID, LeftJoin<INItemQtyCost, On<InventoryItem.inventoryID, Equal<INItemQtyCost.inventoryID>>>>),
typeof(InventoryItem.inventoryCD), typeof(InventoryItem.descr), typeof(INItemQtyCost.qtyAvail)
SubstituteKey = typeof(InventoryItem.inventoryCD),
Filterable = true)]
And can only use my custom selector attribute like this:
[SalesRepCustomer]
The constructor for the PXCustomSelectorAttribute is as follows:
public SalesRepCustomer() : base(typeof(Customer.bAccountID))
{
this.DescriptionField = typeof(Customer.acctName);
this.SubstituteKey = typeof(Customer.acctCD);
}
Is there a way to use the search2<> and so on in a PXCustomSelectorAttribute?
The whole point of a PXCustomSelectorAttribute is to override the "GetItems" method where you define the search function used to return records:
From https://asiablog.acumatica.com/2016/09/custom-selector-attribute.html
public class CustomerPriceClassAttribute : PXCustomSelectorAttribute
{
public CustomerPriceClassAttribute()
: base(typeof(ARPriceClass.priceClassID))
{
this.DescriptionField = typeof(ARPriceClass.description);
}
protected virtual IEnumerable GetRecords()
{
foreach (ARPriceClass pc in PXSelect<ARPriceClass>.Select(this._Graph))
{
yield return pc;
}
}
}
You can use PXSelectJoin or other PXSelect classes if you want.
Utilization of the PXSelectorAttribute
public class SalesRepCustomer : PXSelectorAttribute
{
public SalesRepCustomer() : base(typeof(Search<Customer.bAccountID>))
{
}
}
Usage would be as follows :
public class BatchExtension : PXCacheExtension<Batch>
{
public abstract class usrSalesRepCustomerID : BqlInt.Field<usrSalesRepCustomerID>
{
}
[SalesRepCustomer(SubstituteKey = typeof(Customer.acctName), DescriptionField = typeof(Customer.legalName))]
public int? UsrSalesRepCustomerID
{
get; set;
}
}
Related
I have code
public sealed class GameBoardComponent : IComponent {
}
// next code auto generated
public partial class Entity {
public GameBoardComponent gameBoard { get { return (GameBoardComponent)GetComponent(GameComponentIds.GameBoard); } }
public bool hasGameBoard { get { return HasComponent(GameComponentIds.GameBoard); } }
public Entity AddGameBoard(int newColumns, int newRows) {
var component = CreateComponent<GameBoardComponent>(GameComponentIds.GameBoard);
component.columns = newColumns;
component.rows = newRows;
return AddComponent(GameComponentIds.GameBoard, component);
}
public Entity ReplaceGameBoard(int newColumns, int newRows) {
var component = CreateComponent<GameBoardComponent>(GameComponentIds.GameBoard);
component.columns = newColumns;
component.rows = newRows;
ReplaceComponent(GameComponentIds.GameBoard, component);
return this;
}
public Entity RemoveGameBoard() {
return RemoveComponent(GameComponentIds.GameBoard);
}
}
I want to highlight or click on GameBoardComponent.
And to find all references to gameBoard, hasGameBoard, AddGameBoard, ReplaceGameBoard, RemoveGameBoard.
For AnotherComponent:
public sealed class AnotherComponent : IComponent { }
I would have to find another, hasAnother, AddAnother, ReplaceAnother, RemoveAnother
Is it possible to make a macro\regexp\resharper pattern search or something similar?
P.S. I try use resharper pattern search. But I did not understand how to use for search, selected string(or part of string).
I am trying to create a base class in c# that I can extend out to sub classes.
For example:
public class ObjectsInTheSky
{
public string Size, Shape;
public float Mass;
public int DistanceFromEarth;
public bool hasAtmosphere, hasLife;
public enum ObjectTypes {Planets,Stars,Moons}
public ObjectsInTheSky( int id )
{
this.Load( id );
}
public void Load( int id)
{
DataTable table = Get.DataTable.From.DataBase(id);
System.Reflection.PropertyInfo[] propInfo = this.GetType().GetProperties();
Type tp = this.GetType();
foreach (System.Reflection.PropertyInfo info in propInfo)
{
PropertyInfo p = tp.GetProperty(info.Name);
try
{
if (info.PropertyType.Name == "String")
{
p.SetValue(this, table.Rows[0][info.Name].ToString(), null);
}
else if (info.PropertyType.Name == "DateTime")
{
p.SetValue(this, (DateTime)table.Rows[0][info.Name], null);
}
else
{
p.SetValue(this, Convert.ToInt32(table.Rows[0][info.Name]), null);
}
}
catch (Exception e)
{
Console.Write(e.ToString());
}
}
}
}
public class Planets : ObjectsInTheSky
{
public Moons[] moons;
}
public class Moons : ObjectsInTheSky
{
}
public class Stars : ObjectsInTheSky
{
public StarTypes type;
public enum StarTypes {Binary,Pulsar,RedGiant}
}
My problem is when I try to use an object:
Stars star = new Stars(142);
star.type does not exists and property of star, it exists as star.star.type but completely inaccessable, or I can not figure out how to access it.
I do not know if I'm extending the ObjectsInTheSky property properly or not. Any help or pointers will be greatly appreciated.
It looks as though you are trying to use a constructor that is not defined on your subclass Stars or the base class.
Stars star = new Stars(142);
If you are trying to use the .Load(int) method then you would need to do this:
Stars star = new Stars();
star.Load(142);
Or, if you are trying to use the base constructor, you need to define it in the subclass:
public class Stars : ObjectsInTheSky
{
public Stars(int id) : base(id) // base class's constructor passing in the id value
{
}
public Stars() // in order to not break the code above
{
}
public StarTypes type;
public enum StarTypes {Binary,Pulsar,RedGiant}
}
Constructors in C# are not inherited. You need to add the additional constructor overloads to each of the base classes:
public class Stars : ObjectsInTheSky
{
public Stars(int id) : base(id) { }
public StarTypes type;
public enum StarTypes {Binary,Pulsar,RedGiant}
}
This will create a constructor that just calls the base class's constructor for you.
I have a skinnable Control library that was loads control settings/properties from external xml files.
The Xml classes are in a seperate project as these will be used in a skin editor application, now the question, The controls accept an xml object in the constructor to build the Control but I need to find a nice way to create each control.
Xml class example:
[Serializable]
[XmlInclude(typeof(XmlButton))]
[XmlInclude(typeof(XmlGroup))]
[XmlType(TypeName="Control")]
public class XmlControl
{
[DefaultValue(0)]
public int Width { get; set; }
[DefaultValue(0)]
public int Height { get; set; }
...
and derived types per control type
[Serializable]
[XmlType(TypeName = "Button")]
public class XmlButton : XmlControl
{
public string Label { get; set; }
}
Control classes
public class GUIControl : GUI3DBase
{
public GUIControl(XmlControl skinXml)
{
SkinXml = skinXml;
...
public class GUIButton : GUIControl, IActionControl
{
public GUIButton(XmlControl skinXml) : base(skinXml)
{
}
...
Now this is where I need help, at the moment I have a Method to create controls based on the xml object passed in.
public static GUIControl CreateControl<T>(T skinXml) where T : XmlControl
{
if (skinXml is XmlButton)
{
return new GUIButton(skinXml);
}
else if (skinXml is XmlGroup)
{
return new GUIGroup(skinXml);
}
....
I have about 30 controls and the "if ladder" is growing fast and I feel like I am missing a simple way to create thes controls withou needing to check the xml object type then create the corresponding control type.
I can't add a Type property in the Xml object as that would create circular dependency.
Any help on a good factory method or new stucture layout would be awesome
Maybe IDictionary<Type, Func<XmlControl, GUIControl>> would help. Something like this:
private static Dictionary<Type, Func<XmlControl, GUIControl>> _dictionary = new Dictionary<Type, Func<XmlControl, GUIControl>>()
{
{typeof (XmlControlImpl), x => new GUIControl(x)},
{typeof (XmlGroup), x => new GUIGroup(x)},
};
public static GUIControl CreateControl<T>(T skinXml) where T : XmlControl
{
Func<XmlControl, GUIControl> builder;
if (!_dictionary.TryGetValue(typeof(T), out builder))
throw new KeyNotFoundException("");
return builder(skinXml);
}
Ok, I have found a way to do this with all your ideas and a little reflection, not sure if its the best way but it works nicly and adding a new skinnable control only requires a new xml object and an attribute on the control class.
Attribute Class
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class XmlControlTypeAttribute : Attribute
{
protected Type xmlType;
public XmlControlTypeAttribute(Type xmlType)
{
this.xmlType = xmlType;
}
public Type XmlType
{
get { return this.xmlType; }
}
}
Control:
[XmlControlType(typeof(XmlButton))]
public class GUIButton : GUIControl, IActionControl
{
public GUIButton(XmlControl skinXml) : base(skinXml)
{
}
....
}
Factory method:
public static GUIControl CreateControl2<T>(T skinXml) where T : XmlControl
{
var controlType = Assembly.GetExecutingAssembly().DefinedTypes
.Where(t => t.BaseType == typeof(GUIControl) && t.GetCustomAttribute<XmlControlTypeAttribute>().XmlType.Equals(typeof(T)))
.FirstOrDefault();
return (GUIControl)Activator.CreateInstance(controlType, new[] { skinXml }, null);
}
Thanks for all the ideas the helped heaps, I will leave this question open a bit longer incase somome has a better solution than this.
I would be tempted to add an abstract method to XmlControl:
public abstract class XmlControl
{
[DefaultValue(0)]
public int Width { get; set; }
[DefaultValue(0)]
public int Height { get; set; }
public abstract Type ControlType();
override it in each implementation eg:
public class XmlButton : XmlControl
{
public string Label { get; set; }
public override Type ControlType(){ return typeof(GUIButton); }
}
And then use reflection in the Factory method to construct the right class:
public static GUIControl CreateControl<T>(T skinXml) where T : XmlControl
{
return (GUIControl)Activator.CreateInstance(skinXml.ControlType(),
new[]{skinXml},null);
}
I got an abstract base class
public class Base
{
public abstract String Info { get; }
}
and some children.
public class A : Base
{
public override String Info { get { return "A does ..."; } }
}
public class B : Base
{
public override String Info { get { return "B does ..."; } }
}
This is mere a constant but I want to make sure using Base that all classes implement it.
Now I sometimes do not have an object instance but want to access A.Info - this is not possible due it is a instance property.
Is there another way than implementing the same property on instance AND on static level? That would be feel like a duplicate violating DRY programming style.
NEW EDIT: I now see this two solutions:
public class Base
{
public abstract String ClassInfo { get; }
}
public class A : Base
{
public override String ClassInfo { get { return Info; } }
public static String Info { get { return "A does ..."; } }
}
public class B : Base
{
public override String ClassInfo { get { return Info; } }
public static String Info { get { return "In B we do ..."; } }
}
With this I can do with any object of type Base something like object.ClassInfo but also use the value in my factory hardcoded like if(A.Info) return new A(). But I have to implement two properties for the same information in every class.
On the other hand:
public class Base
{
public abstract String ClassInfo { get; }
public static String GetClassInfo<T>() where T : BaseControl, new()
{
T obj = new T();
return obj.ClassInfo;
}
}
public class A : Base
{
public override String ClassInfo { get { return "text A"; } }
}
public class B : Base
{
public override String ClassInfo { get { return "text B"; } }
}
Due to the abstract Base it is made sure that ClassInfo is always implemented. Calls with obj.ClassInfo and Base.GetClassInfo<A>() are okay. But with this every child of Base must have a default constructor without arguments and we loose performance with the unneccessary created instance.
Is there any other idea? Which one would you prefer and why?
If you need specific return results of your static properties, you're better of either
a) Instance properties
2) Attributes
In the example you've already given, you've got an instance of Base, which means you can just make the instance property virtual:
public class Base
{
public virtual string Info { get { return "From Base"; } }
}
public class A : Base
{
public override string Info { get { return "From A"; } }
}
If you wanted to go the attribute route, you define it as such:
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class InfoAttribute : Attribute
{
public InfoAttribute(string info) { this.Info = info; }
public string Info { get; private set; }
}
[InfoAttribute(Info = "From Base")]
public class Base
{
public string GetInfo()
{
var attr = GetType()
.GetCustomAttributes(typeof(InfoAttribute), true)
.FirstOrDefault();
return (attr == null) ? null : attr.Info;
}
}
[InfoAttribute(Info = "From A")]
public class A : Base { }
If you wanted to call it as a static function call, you could make this change:
public static string GetInfo(Base instance)
{
var attr = instance.GetType()
.GetCustomAttributes(typeof(InfoAttribute), true)
.FirstOrDefault();
return (attr == null) ? null : attr.Info;
}
And then call it as: Base.GetInfo(instance);. All in all, not very elegant!
This is not possible.
static members cannot be virtual or abstract.
You should make an abstract instance property.
Statics can't be overridden. If you truly want to do something like that, you'd want an instance property that is virtual in the base that gets overridden in the subclasses.
Does it compiled? I don't think so. Static cannot be marked as override, virtual or abstract.
I have my domain model with several NewsType's which are subclasses of NewsItem as shown below (simplified):
public abstract class NewsItem : Entity
{
public virtual Account Account { get; set; }
public virtual DateTime DateTime { get; set; }
}
Here are a couple of subclasses of NewsItem:
public class NewsItemJoiner : NewsItem
{
public virtual Account AccountJoined { get; set; }
}
public class NewsItemStatus : NewsItem
{
public virtual string Status { get; set; }
}
In my MVC app I want to return a collection of Newsitem's which may contain many different subclasses of NewsItem. Is what I now need to do is loop through each news item and call a Render function from the relevant class for that specific type of NewsItem...code might explain it a little easier:
public interface IRenderer<T> where T : NewsItem
{
string Render(T item);
}
public class JoinedRenderer : IRenderer<NewsItemJoiner>
{
public string Render(NewsItemJoiner item)
{
return String.Format("{0} has just joined our music network.", item.AccountJoined.ArtistName);
}
}
public class StatusUpdateRenderer : IRenderer<NewsItemStatus>
{
public string Render(NewsItemStatus item)
{
return String.Format("<span class='statusupdate'>{0}<span>", item.Status);
}
}
I need to somehow call the correct classes Render function depending on the type of NewsItem.
This seems like a rather obvious case for a virtual function.....
public abstract class RenderableNewsItem : NewsItem
{
abstract public string Render();
}
public class NewsItemStatus : RenderableNewsItem
{
public virtual string Status { get; set; }
public string Render()
{
return String.Format("<span class='statusupdate'>{0}<span>", this.Status);
}
}
You could make a Dictionary that used the type of NewsItem as a key and the Render function to be used as a value. Or, you could maintain a list of all of the classes with Render functions or just of all the Render functions and use Reflection to determine which method should be used. However, it seems to me that instead of doing any of this you should consider redesigning your application so that the NewsItem abstract class itself has a virtual Render function. This would greatly simplify your task.
Edit: Previously thought NewsItem was an interface.
One possibility: on startup (i.e. in a static constructor related to your rendering code), iterate through the classes in your assembly and instantiate and store a Dictionary<Type, object> of IRenderer<T>-implementing instances mapped to the type that they render.
(This suggestion assumes that the renderer objects are thread-safe, since you may end up calling the Render method from more than one request thread at one time. If they're not thread safe, then you'd need to change the dictionary to <Type, Type> and instantiate a renderer for each use.)
For example:
public class RenderUtil
{
static Dictionary<Type, object> s_renderers;
static RenderUtil()
{
s_renderers = new Dictionary<Type, object>();
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
var renderInterface = type.GetInterfaces().FirstOrDefault(
i => i.IsGenericType &&
i.GetGenericTypeDefinition() == typeof(IRenderer<>));
if (renderInterface != null)
{
s_renderers.Add(
renderInterface.GetGenericArguments()[0],
Activator.CreateInstance(type));
}
}
}
public static string Render<T>(T item)
{
IRenderer<T> renderer = null;
try
{
// no need to synchronize readonly access
renderer = (IRenderer<T>)s_renderers[item.GetType()];
}
catch
{
throw new ArgumentException("No renderer for type " + item.GetType().Name);
}
return renderer.Render(item);
}
}
Usage:
var newsItem = new NewsItemStatus();
// in your example code, ends up calling StatusUpdateRenderer.Render:
var rendered = RenderUtil.Render(newsItem);
Note that the RenderUtil class will throw a DuplicateKeyException via a TypeInitializationException on first use if there is more than one renderer for a given type.
What I would do instead is have multiple partial views for rendering different NewsItem subclasses. Then, I would have some sort of mapping between the subclasses and the partial view names. Here's two ways to do this:
NewsItem could have a virtual string property/method that returns the name of the partial view associated with it. I'd only recommend this if NewsItem is a specifically a model class used to pass into views, not if it's an ORM class or similar.
In the model containing the list of news items, you could have a mapping property (a Dictionary<Type, string> for example).
Once you have this set up, your view could look something like this:
<% foreach (var newsItem in Model.NewsItems) { %>
<%= Html.RenderPartial(newsItem.PartialViewName, newsItem) %>
<% } >
I just did something like this, but I don't have the code handy. It used Reflection and looked like the following:
List<GenericContainer> gcList = new List<GenericContainer>();
// GenericContainer can be a Jug, Bottle, Barrel, or just a GenericContainer type
// [..fill it..]
GenericContainer gc = gcList[i];
Object returnvalue = gc.GetType()
.GetMethod("Pour", BindingFlags.Instance).Invoke(gc, null);
Consider inverting the control logic and providing a virtual Render() method in NewsItem instead. E.g.
abstract class NewsItem {
// ...
public virtual string Render() { return string.Empty; }
}
Then your subclass can implement as desired:
public class NewsItemJoiner : NewsItem
{
// ...
public override string Render() {
return String.Format("{0} has just joined our music network.", this.AccountJoined.ArtistName);
}
}
Edit:
Alternative Technique
Point taken about the comments from others re separation of concerns. I don't know if you're set on the IRenderer<T> for other reasons, but if you aren't, there's another technique which doesn't need to use reflection. You could use the Visitor pattern instead.
First you declare a NewsItemVisitor class:
public abstract class NewsItemVisitor
{
public abstract void Visit(NewsItemJoiner joiner);
public abstract void Visit(NewsItemStatus status);
}
Next, add a virtual Accept() method to NewsItem (for this example, I've changed your data types to string instead of Account, Status etc):
public abstract class NewsItem
{
public virtual string Account { get; set; }
public virtual DateTime DateTime { get; set; }
public abstract void Accept(NewsItemVisitor visitor);
}
public class NewsItemJoiner : NewsItem
{
public virtual string AccountJoined { get; set; }
public override void Accept(NewsItemVisitor visitor)
{
visitor.Visit(this);
}
}
public class NewsItemStatus : NewsItem
{
public virtual string Status { get; set; }
public override void Accept(NewsItemVisitor visitor)
{
visitor.Visit(this);
}
}
Now you can create a concrete Visitor, which is our renderer:
public class NewsItemListRenderer : NewsItemVisitor
{
private readonly List<NewsItem> itemList;
private string renderedList = string.Empty;
public NewsItemListRenderer(List<NewsItem> itemList)
{
this.itemList = itemList;
}
public string Render()
{
foreach (var item in itemList)
{
item.Accept(this);
}
return renderedList;
}
public override void Visit(NewsItemJoiner joiner)
{
renderedList += "joiner: " + joiner.AccountJoined + Environment.NewLine;
}
public override void Visit(NewsItemStatus status)
{
renderedList += "status: " + status.Status + Environment.NewLine;
}
}
Sample code for how to render a list of NewsItem instances:
List<NewsItem> itemList = new List<NewsItem>();
itemList.Add(new NewsItemJoiner { AccountJoined = "fred" });
itemList.Add(new NewsItemJoiner { AccountJoined = "pete" });
itemList.Add(new NewsItemStatus { Status = "active" });
itemList.Add(new NewsItemJoiner { AccountJoined = "jim" });
itemList.Add(new NewsItemStatus { Status = "inactive" });
NewsItemListRenderer renderer = new NewsItemListRenderer(itemList);
Console.WriteLine(renderer.Render());
Running this gives the following output:
joiner: fred
joiner: pete
status: active
joiner: jim
status: inactive