The order of the members can be set up in the ReSharper options in Languages, C#, Type Members Layout. Resharper is doing it correctly. However, I would like to exclude certain classes which contain JSONProperty attribute.
So for example, refer class below. I don't want Resharper to reorder the members in it.
internal class ExecutionParametersJson
{
[JsonProperty("Factor")]
public string Factor { get; set; }
[JsonProperty("Penalty")]
public string Penalty { get; set; }
[JsonProperty("Origin")]
public string Origin { get; set; }
[JsonProperty("InterFactor")]
public string InterFactor { get; set; }
}
I am using latest version of Resharper.
Can anyone show me how to configure Resharper to achieve this?
Actually, I tried putting Order attribute in it. But that didn't do any difference.
[JsonProperty("Factor", Order = 1)]
public string Factor{ get; set; }
However, I would like to exclude certain classes which contain JSONProperty attribute.
Yes that can be done rather easily.
Given this exammple code, note the additional properties I included purely to prove a later point:
internal class ExecutionParametersJson
{
[JsonProperty("Factor")]
public string Factor { get; set; }
public string SomeProperty { get; set; }
[JsonProperty("Penalty")]
public string Penalty { get; set; }
[JsonProperty("Origin")]
public string Origin { get; set; }
public int SomeOtherProperty { get; set; }
[JsonProperty("InterFactor")]
public string InterFactor { get; set; }
}
...then choose Resharper.Options.Code Editing.c#.File Layout, the list of patterns appears:
Choose your preferred pattern. Here I chose Default Pattern. I've been adding to it in the past so it may look different.
Scroll down till you find a region for Properties, you may have to create it like so:
Select Properties, Indexers, ensure Sort By is set to Name.
Double-click Properties, Indexers. The conditions editor appears. Add a top-level And condition; Not and specify the JsonProperty.
Now run Resharper.Edit.Cleanup Code on the file in question. All properties, except those with a JsonProperty attribute, will be sorted alphabetically and placed into a region titled Properties.
internal class ExecutionParametersJson
{
#region Properties
public int SomeOtherProperty { get; set; }
public string SomeProperty { get; set; }
#endregion
[JsonProperty("Factor")]
public string Factor { get; set; }
[JsonProperty("Penalty")]
public string Penalty { get; set; }
[JsonProperty("Origin")]
public string Origin { get; set; }
[JsonProperty("InterFactor")]
public string InterFactor { get; set; }
}
Now the additional properties I included here was just to prove how you format members conditionally. Feel free to remove these properties; the #region or customise to your liking.
Moving on
You may want to tidy this up a bit and create a specific pattern in Resharper called JSON Classes or some such.
Related
I have some classes that are created and maintained by Entity Framework. These classes represent tables in my DB. In two of these tables, I have very similar fields. For example (pseudo-objects):
public class RandomObject1
{
int Identifier { get; set; }
int ObjectType { get; set; }
int SourceID { get; set; }
string OriginationPont { get; set; }
string PhoneNumber { get; set; }
decimal Cost { get; set; }
int OtherThing1 { get; set; }
int OtherThing2 { get; set; }
int OtherThing3 { get; set; }
}
public class RandomObject2
{
int Identifier { get; set; }
int ObjectType { get; set; }
int SourceID { get; set; }
string OriginationPont { get; set; }
string PhoneNumber { get; set; }
decimal Cost { get; set; }
double CashValue1 { get; set; }
decimal Snowman2 { get; set; }
int BigFurryTree3 { get; set; }
}
Note that the first few fields of these two objects are the same, and the processes for populating those fields are also the same. Normally in these situations I would have an interface that declares just the first few fields so that I can pass this object as an interface to various processes.
However, in this case, I don't control the code that builds these classes, and really don't want to have to edit the resulting .cs files from the Entity Framework every time it is regenerated.
I was wondering if there is a slick way that I am missing to use generics to do something like the following:
// This method will populate SourceID, OriginationPoint, PhoneNumber and Cost
public void GenerateOriginationInformation<T>(ValidationInformation info, T objectToManipulate) where T : RandomObject1 || RandomObject2
{
objectToManipulate.SourceID = GenerateSourceID(info);
objectToManipulate.OriginationPoint = GenerateOriginationPoint(info);
objectToManipulate.PhoneNumber = FindPhoneNumberByOrigination(info);
objectToManipulate.Cost = DetermineCostBySourceAndOrigination(info);
}
Right now, I have to build an entire object/layer that will populate and return the correct object, but results in me doing most of the code for these things twice!
public void GenerateOriginationInformation(ValidationInformation into, RandomObject1 objectToManipulate)
{
objectToManipulate.SourceID = GenerateSourceID(info);
objectToManipulate.OriginationPoint = GenerateOriginationPoint(info);
objectToManipulate.PhoneNumber = FindPhoneNumberByOrigination(info);
objectToManipulate.Cost = DetermineCostBySourceAndOrigination(info);
}
public void GenerateOriginationInformation(ValidationInformation into, RandomObject2 objectToManipulate)
{
objectToManipulate.SourceID = GenerateSourceID(info);
objectToManipulate.OriginationPoint = GenerateOriginationPoint(info);
objectToManipulate.PhoneNumber = FindPhoneNumberByOrigination(info);
objectToManipulate.Cost = DetermineCostBySourceAndOrigination(info);
}
At first, this doesn't look too bad, but this code is highly over-simplified for the purposes of explanation and brevity. Is there a cleaner way to use generics to get the two methods to work as one since I can't implement an interface?
I don't control the code that builds these classes, and really don't want to have to edit the resulting .cs files from the Entity Framework every time it is regenerated
answer in comment: "it is EDMX"
The generated classes from your EDMX designer are partial by default (no additional work necessary by you) so you can create a code file next to the generated files with a partial as well in which you make the type implement an interface.
Generated class
public partial class RandomObject1
Your code file placed in the same project
public partial class RandomObject1 : ICommonInterface
The classes that are generated by Entity Framework are probably "partial". This means that you can write your own partial class to add features of your own to that generated class.
Such as this:
public partial class RandomObject1: ICommonInterface
{
}
With "ICommonInterface" an interface that specified the shared properties.
public String name
{
get;
set;
}
public String email
{
get;
set;
}
public String address
{
get;
set;
}
Is there an easier way to declare multiple variables with same property under one accessibility like this?
Something like
public String name, email, address
{
get;
set;
}
You could package them together in a separate class and then use that as a property:
class Info
{
public String name { get; set; }
public String email { get; set; }
public String address { get; set; }
}
class Person
{
public Info info { get; set; }
}
Obviously it's not what you're after in terms of inlining, but it does present a cleaner option if Info is something you'd use in more than one place. If you're not going to use that class anywhere else, then it's pointless.
Note, as an aside, that I'm using your conventions for capitalization of properties, but it's a "convention" to use Pascal case.
If you don't care for OOP and just want a bunch of strings collected in one variable you can do this with a simple Tuple in your case. It would look like this.
var bunchOfStrings = new Tuple<String,String,String>(String.Empty,String.Empty,String.Empty);
Console.Writeline("{0},{1},{2}",bunchOfStrings.Item1
,bunchOfStrings.Item2
,bunchOfStrings.Item3);
But keep in mind, you hide information with this approach. The items are just numbered and you loose any connection to the semantic of the items.
I want to have below class properties to be displayed in PropertyGrid not in the declared order, instead specified attribute? is there such attribute for?
As:
A
B
C
Thanks.
public class ApplicationConfiguration
{
public ApplicationConfiguration()
{
}
public int A { get; set; }
public int C { get; set; }
public int B { get; set; }
}
If you are sending this object from an MVC/WCF application you can use DataMember attribute like below
public class ApplicationConfiguration
{
public ApplicationConfiguration()
{
}
[DataMember(Order=1)]
public int A { get; set; }
[DataMember(Order = 3)]
public int C { get; set; }
[DataMember(Order = 2)]
public int B { get; set; }
}
You have many options in deciding how instances of your classes should appear in the property grid. Start off with Design-Time Attributes for Components and go from there.
See Extending Design-Time Support for the big picture. The bottom line is that you can easily cause your properties to display grouped by categories just by adding [Category("categoryName")] attributes. But if you need them to appear in a completely different order from their order of declaration, then you need to create a Designer.
I have the following class structure in my application:
[ProtoContract]
public abstract class WebSyncedObject
{
[ProtoMember(1)]
public DateTime SystemTime { get; set; }
[ProtoMember(2)]
public bool TimeSynchronized { get; set; }
[ProtoMember(3)]
public ulong RelativeTime { get; set; }
[ProtoMember(4)]
public Guid BootID { get; set; }
protected WebSyncedObject()
{
BootID = BootID.GetBootID();
if (BootID == Guid.Empty) return;
TimeSynchronized = Time.TimeSynchronized;
RelativeTime = Time.RelativeTime;
SystemTime = DateTime.Now;
}
}
[ProtoContract]
public class GPSReading : WebSyncedObject
{
[ProtoMember(1)]
public DateTime SatelliteTime { get; set; }
[ProtoMember(2)]
public decimal Latitude { get; set; }
[ProtoMember(3)]
public decimal Longitude { get; set; }
[ProtoMember(4)]
public int NumSatellites { get; set; }
[ProtoMember(5)]
public decimal SpeedKM { get; set; }
}
[ProtoContract]
public class TemperatureReading : WebSyncedObject
{
[ProtoMember(1)]
public decimal Temperature { get; set; }
[ProtoMember(2)]
public int NodeID { get; set; }
[ProtoMember(3)]
public string ProbeIdentifier { get; set; }
}
I then construct a List<WebSynchedObject> with data of both types, and try to serialize with Protobuf-net when I get the following exception:
InvalidOperationException
Unexpected sub-type: Logger.TemperatureReading
I've read about the ProtoInclude attribute, but I don't want to use that as my code needs to be easily extendable, and I'm not sure on how the numbering on the RuntimeTypeModel approach is supposed to work, since I've also seen warnings about generating that automagically.
Is there any way to achieve this whilst making it extendable?
Ultimately, there needs to be a robust, reliable and repeatable way of the library identifying a specific sub-type (GPSReading, etc) with a unique identifier (a field-number). In many cases, the most convenient way to do that is via attributes. However, if this is not an option, you can also do this at runtime - perhaps reading the identifiers some configuration file. It would not be a good idea to just say (at runtime) "find all the available sub-types, order them alphabetically, and increment them starting at (say) 10", because in a later build you might have added an AltitudeReading, which would change the number of everything, breaking the existing data. But as long as you can define these in a repeatable manner, then all is good. For example, with attributes...
[ProtoInclude(10, typeof(GPSReading))]
[ProtoInclude(11, typeof(TemperatureReading))]
[ProtoInclude(12, typeof(AltitudeReading))]
But you could also do something in a text file, or an xml configuration file... maybe:
<add key="10" type="Some.Namespace.GPSReading"/>
<add key="11" type="Some.Namespace.TemperatureReading"/>
<add key="12" type="Some.Namespace.AltitudeReading"/>
and add you own code that reads the config file, and calls:
int key = int.Parse(element.GetAttributeValue("key"));
Type type = someAssembly.GetType(element.GetAttributeValue("type"));
RuntimeTypeModel.Default[typeof(WebSyncedObject)].AddSubType(key, type);
Again, to emphasize: the important thing is that the numbers associated with each sub-type must be robustly repeatable in the future. As long as you can guarantee that, it is not required to use attributes. But the model does need to know the identifiers.
Can an arbitrary number of ContentItems of the same class to be added to a page in N2? And can they be nested?
I.e. Is there a way to define a collection of ContentItems as a property in N2? I’d also like to nest these if possible so we can run more meaningful queries against the data. (I.e. instead of using huge EditableTextRegions which will be difficult to query.)
I currently have the following model as an ‘ideal’, can this be N2ified? (I’ve left off attributes and N2 style getters/setters for clarity)
public class Link : ContentItem
{
public string Text { get; set; }
public string Title { get; set; }
public string Url { get; set; }
}
public class Panel : ContentItem
{
public string Title { get; set; }
public string Text { get; set; }
public List<Link> Links { get; set; } // Should show an expandable number of “Link” editors in the CMS editor
public string ImageUrl { get; set; }
}
public class Page : ContentItem
{
public string Title { get; set; }
public string BodyText { get; set; }
public List<Panel> Panels { get; set; } // Should show an expandable number of “Panel” editors in the CMS editor
}
Yes - instead of Get/SetDetail in your properties use Get/SetDetailCollection.
FYI if you're using 2.1 you can just make your properties virtual and leave off the Get/SetDetail - not sure if this works for the DetailCollection methods though, but you can mix the two.
I'd be careful with what you're proposing though - nesting collections like this is likely to cause you SELECT N+1 issues down the line. If you can't change the design then I'd recommend turning on N2's database caching (which is just NHibernate's 2nd level cache), this way as much as possible will be kept in memory without hitting the database too much.