Removing literal strings in .net code - c#

What have you done to remove (Helpers/extension methods) string literal in code?
e.g. I have nhibernate search criteria code like this all over the place.
Expression.Eq("Status", LoginStatus.LoggedIn),
“Status” being the property of an entity object used as a string in the case.
Update: Primary reason in this case is to enable refactoring. If I write a helper method which reflects the object and gets the value, will make the above expression strongly typed.

This is what "Resources" and "Settings" is for. You can find this by right clicking your project in Visual Studio and clicking "Properties", then going to the "Resources" or "Settings" tab.
For pre-built resources that won't change often, use resources. For things you want to be configurable use Settings instead because it will auto-generate blocks of configuration for your App.config. You will still need to manually copy and paste these values if you do not want to use the defaults.
The nice thing about both is that VS will build a nice static class with properties you can use throughout your code. VS will maintain the class and resources for you dynamically as long as you continue to use the wizard.

I'll usually declare them as constants, or, if I have groups of related strings, I'll create an enum instead.
Either way, at least they have a descriptive name attached to them (instead of using "magic strings"), and their use will always be consistent.

In the past, I've used CodeRush (or your favourite refactoring tool) to convert to a const string in the class, and then moved said const strings to be public members of the entity class to which they apply.
The real answer here, if you're looking to get your code less brittle in the face of refactoring is to get out of the strings business, and use Linq 4/to NHibernate, but you'd have to research whether it's completeness is sufficeint for your purposes.

Realized that I could do this the Expression trees way. Using Code as data!
Something like this
protected IList<T> _FindByProperty<TResult>(Expression<Func<T, TResult>> expression, TResult value)
{
return _FindByProperty((expression.Body as MemberExpression).Member.Name, value);
}
IList<User> costCenters = _FindByProperty( user=> user.Name, "name");
Credits: http://suryagaddipati.wordpress.com/2009/03/14/code-as-data-in-c-taking-advantage-of-expression-trees/
This is related to a lot questions in the expression-trees tag.

I use a similar approach as Cherian. I got my idea from the FluentNhibernate's ReflectionHelper.
The principle is to use expression trees and then you could just put in a x => x.Status expression. The method would return the property name as string.
In fact, you could also just use FluentNHibernate? However, I don't know if their querying model is evenly extensive as their mapping interfaces...

Related

what will be the Regular Expression to get all the property and variables names of a class in c#?

What will be the Regular Expression to get all the property and variables names of any class in c#, I want to parse the *.cs file. that is i want to select any *.cs file as input and it should get the property name of that selected class, as an output.
can any one help!!!....would appreciate for any help i tried very much but not got the actual result every time class name is coming instead of property.
thanks
Jack
There's no way you're going to be able to get exactly what you want with a regular expression because you need semantic context, not just string parsing.
For example, a good first attempt at finding all of the field and property definitions in a C# file might go something like this
^\s*(?:(?:private|public|protected|internal)\s+)?(?:static\s+)?(?:readonly\s+)?(\w+)\s+(\w+)\s*[^(]
That will match properties (public int Foo {...}) and fields (private int foo;) but not methods (protected void Bar()).
The problem is that a regex engine has no concept of the context within which those tokens appear. It will match both foo and bar in this code:
int foo;
void Stuff()
{
int bar;
}
If you happen to know that your code file follows some coding standards, you may have more luck. For example, if you enforce a style rule that all class members must have access specifiers, then you can make the private/public/etc part of that regex non-optional; since those are only permitted at the class level, it will filter out local variables.
There are other options, none of them too attractive at first glance. There is persistent talk from the C# dev team about exposing the C# compiler as a service in some future version of .NET, which would be perfect here, but I wouldn't expect that any time soon. You could purchase a third-party C# parser/analyzer like this one (caveat: I have zero experience with that, it's just the first Google hit). You could try compiling the .cs file using csc and examining the IL, but you'd need to know all of the third-party references.

LINQ-like or SQL-like DSL for end-users to run queries to select (not modify) data?

For a utility I'm working on, the client would like to be able to generate graphic reports on the data that has been collected. I can already generate a couple canned graphs (using ZedGraph, which is a very nice library); however, the utility would be much more flexible if the graphs were more programmable or configurable by the end-user.
TLDR version
I want users to be able to use something like SQL to safely extract and select data from a List of objects that I provide and can describe. What free tools or libraries will help me accomplish this?
Full version
I've given thought to using IronPython, IronRuby, and LuaInterface, but frankly they're all a bit overpowered for what I want to do. My classes are fairly simple, along the lines of:
class Person:
string Name;
int HeightInCm;
DateTime BirthDate;
Weight[] WeighIns;
class Weight:
int WeightInKg;
DateTime Date;
Person Owner;
(exact classes have been changed to protect the innocent).
To come up with the data for the graph, the user will choose whether it's a bar graph, scatter plot, etc., and then to actually obtain the data, I would like to obtain some kind of List from the user simply entering something SQL-ish along the lines of
SELECT Name, AVG(WeighIns) FROM People
SELECT WeightInKg, Owner.HeightInCm FROM Weights
And as a bonus, it would be nice if you could actually do operations as well:
SELECT WeightInKg, (Date - Owner.BirthDate) AS Age FROM Weights
The DSL doesn't have to be compliant SQL in any way; it doesn't even have to resemble SQL, but I can't think of a more efficient descriptive language for the task.
I'm fine filling in blanks; I don't expect a library to do everything for me. What I would expect to exist (but haven't been able to find in any way, shape, or form) is something like Fluent NHibernate (which I am already using in the project) where I can declare a mapping, something like
var personRequest = Request<Person>();
personRequest.Item("Name", (p => p.Name));
personRequest.Item("HeightInCm", (p => p.HeightInCm));
personRequest.Item("HeightInInches", (p => p.HeightInCm * CM_TO_INCHES));
// ...
var weightRequest = Request<Weight>();
weightRequest.Item("Owner", (w => w.Owner), personRequest); // Indicate a chain to personRequest
// ...
var people = Table<Person>("People", GetPeopleFromDatabase());
var weights = Table<Weight>("Weights", GetWeightsFromDatabase());
// ...
TryRunQuery(userInputQuery);
LINQ is so close to what I want to do, but AFAIK there's no way to sandbox it. I don't want to expose any unnecessary functionality to the end user; meaning I don't want the user to be able to send in and process:
from p in people select (p => { System.IO.File.Delete("C:\\something\\important"); return p.Name })
So does anyone know of any free .NET libraries that allow something like what I've described above? Or is there some way to sandbox LINQ? cs-script is close too, but it doesn't seem to offer sandboxing yet either. I'd be hesitant to expose the NHibernate interface either, as the user should have a read-only view of the data at this point in the usage.
I'm using C# 3.5, and pure .NET solutions would be preferred.
The bottom line is that I'm really trying to avoid writing my own parser for a subset of SQL that would only apply to this single project.
There is a way to sandbox LINQ or even C#: A sandboxed appdomain. I would recommend you look into accepting and compiling LINQ in a locked-down domain.
Regarding NHibernate, perhaps you can pass the objects into the domain without exposing NHibernate at all (I don't know how NHibernate works). If this is not possible, perhaps the connection to the database used within the sandbox can be logged in as a user who is granted only SELECT permissions.
Maybe the expressions will come handy for You.
You could provide simple entry places for:
a) what to select - user is expected to enter an expression only _ probably member and arithmetic expressions - those are subclasses of the expression class
b) how to filter the things = again only expressions are expected
c) ordering
d) joining?
Expressions don't let You do File.Delete because You operate only on precise domain objects (which probably don't have this functionality). The only thing You have to check is whether the parameters of the said expressions are of Your domain types. and Return types of said expressions are of domain types (or generic types in case of IEnumerable<> or IQuerable<>
this might prove helpful
I.E. expressions don't let You write multi-line statements.
Then You build your method chain in code
and voila.
There comes the data
I ended up using a little bit of a different approach. Instead of letting users pick arbitrary fields and make arbitrary graphs, I'm still presenting canned graphs, but I'm using Flee to let the user filter out exactly what data is used in the source of the graph. This works out nicely, because I ended up making a set of mappings from variable names to "accessors", and then using those mappings to inject variables into the user-entered filters. It ended up something like:
List<Mapping<Person>> mappings;
// ...
mappings.Add(new Mapping("Weight", p => p.Weight, "The person's weight (in pounds)"));
// ...
foreach (var m in mappings)
{
context.Variables[m.Name] = m.Accessor(p);
}
// ...
And you can even give an expression context an "owner" (think Ruby's instance_eval, where the context is executed with score of the specified object as this); then the user can even enter a filter like Weight > InputNum("The minimum weight to see"), and then they will be prompted thusly when the filter is executed, because I've defined a method InputNum in the owning class.
I feel like it was a good balance between effort involved and end result. I would recommend Flee to anyone who has a need to parse simple statements, especially if you need to extend those statements with your own variables and functions as well.

PostSharp for an object mapper

I'm considering using PostSharp for entity-to-DTO and DTO-to-entity mapper. To do that task manualy for about a 100 entities would be a maintenence nightmare. I've looked at AutoMapper on codeplex, but i think the overhead might be a serious problem in my case, besides i feel that PostSharp could give me some extra control over the mapping convention. If anyone can share any experiences with this king of problems, that would be great.
The direction i'm think in is something like this (please somebody tell me if this is not possible):
The aspect that i am planing to stick to a class would fill the next two methods with content:
EntityType EntityToDTO(DTOType DTO) {}
DTOType DTOToEntity(EntityType Entity) {}
The first method would return entity based on DTO, the second one would do the oposite. Inside the aspect i'm planing to loop through each property, create new target and asign the value of a property to the counterpart from target object. Is this possible to do at compiletime witout any runtime overhead?
If your DTOs field names match your entity field names, then I'd use Duck Typing
http://www.deftflux.net/blog/page/Duck-Typing-Project.aspx
http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx
Your code would work like this
UserDTO user = DuckTyping.Cast<UserDTO>(userEntity);
Basically, the duck typing library will be mapping over the fields by matching the names. They use dynamically generated IL to archive this.
If that has the potential of being too slow, I'd probably try to get CodeSmith to generate the methods for me.
If it helps, there is a project called PostSharp4ET that basically implements support for POCO objects to Entity Framework 1. See http://www.codeplex.com/efcontrib.
Note that PostSharp is not very good at generating new code. It is good at mixing new code with existing one. If you need to generate code, I would recommend writing a C# code generator based on reflection, and compile the resulting code. Or use a tool like CodeSmith, as mentioned previously.

C#: Attrbute for intellisense to show method only outside of assembly

Basically what I'm hoping for is something that would work like how the Obsolete attribute works with Intellisense and strikes the method text when typing out the name. What I'm looking for is an attribute that blocks the method from being seen with the assembly it's defined. Kind of like an reverse internal. Using 3.5 by the by.
Yeah sounds odd but if you need the reason why, here it is:
My current solution for lazy loading in entity framework involves having the generated many to one or one to one properties be internal and have a facade? property that is public and basically loads the internal property's value:
public ChatRoom ParentRoom
{
get
{
if(!ParentRoomInnerReference.IsLoaded)
{
ParentRoomInnerReference.Load();
}
return ParentRoomInner;
}
set
{
ParentRoomInner = value;
}
}
Problem with this is if someone tries to use the ParentRoom property in a query:
context.ChatItem.Where(item => item.ParentRoom.Id = someId)
This will blow up since it doesn't know what to do with the facade property when evaluating the expression. This isn't a huge problem since the ParentRoomInner property can be used and queries are only in the entity assembly. (IE no selects and such in the UI assembly) The only situation comes in the entity assembly since it can see both properties and it's possible that someone might forget and use the above query and blow up at runtime.
So it would be nice if there were an attribute or some way to stop the entity assembly from seeing (ie blocked by intellisense) the outward facing properties.
Basically inside the assembly see ParentRoomInner. Outside the assembly see ParentRoom. Going to guess this isn't possible but worth a try.
I do see that there is an attribute
for stopping methods from being
viewable
(System.ComponentModel.EditorBrowsable)
but it's choices are rather slim and
don't really help.
You can use the EditorBrowsableAttribute for this:
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public void MyMethod() {}
One thing to know, though: In c#, you will still get intellisense on the method if it is in the same assembly as the one you are working in. Someone referencing your assembly (or your project, for a project reference) will not see it though. You can also pass EditorBrowsableState.Advanced, and then you will only get intellisense if c# if you clear the HideAdvancedMembers option in Tools Options.
I haven't heard of a good way to do this in plain .NET. But, here are some ideas. Maybe one of them will work, or set you off in a direction that will be helpful.
Use FxCop, probably writing your own rule to make sure ParentRoom isn't called from the asslembly that defined it.
Look into the various post-processing projects for .NET (link design-by-contract).
Write some code inside your ParentRoom getter which will check the stack (using "new Stack()" or "new StackFrame(1)" to figure out whether the caller was from the same assembly. If so, either throw an exception or simply return ParentRoomInner.

Dynamic "WHERE" like queries on memory objects

What would be the best approach to allow users to define a WHERE-like constraints on objects which are defined like this:
Collection<object[]> data
Collection<string> columnNames
where object[] is a single row.
I was thinking about dynamically creating a strong-typed wrapper and just using Dynamic LINQ but maybe there is a simpler solution?
DataSet's are not really an option since the collections are rather huge (40,000+ records) and I don't want to create DataTable and populate it every time I run a query.
What kind of queries do you need to run? If it's just equality, that's relatively easy:
public static IEnumerable<object[]> WhereEqual(
this IEnumerable<object[]> source,
Collection<string> columnNames,
string column,
object value)
{
int columnIndex = columnNames.IndexOf(column);
if (columnIndex == -1)
{
throw new ArgumentException();
}
return source.Where(row => Object.Equals(row[columnIndex], value);
}
If you need something more complicated, please give us an example of what you'd like to be able to write.
If I get your point : you'd like to support users writting the where clause externally - I mean users are real users and not developers so you seek solution for the uicontrol, code where condition bridge. I just though this because you mentioned dlinq.
So if I'm correct what you want to do is really :
give the user the ability to use column names
give the ability to describe a bool function (which will serve as where criteria)
compose the query dynamically and run
For this task let me propose : Rules from the System.Workflow.Activities.Rules namespace. For rules there're several designers available not to mention the ones shipped with Visual Studio (for the web that's another question, but there're several ones for that too).I'd start with Rules without workflow then examine examples from msdn. It's a very flexible and customizable engine.
One other thing: LINQ has connection to this problem as a function returning IQueryable can defer query execution, you can previously define a query and in another part of the code one can extend the returned queryable based on the user's condition (which then can be sticked with extension methods).
When just using object, LINQ isn't really going to help you very much... is it worth the pain? And Dynamic LINQ is certainly overkill. What is the expected way of using this? I can think of a few ways of adding basic Where operations.... but I'm not sure how helpful it would be.
How about embedding something like IronPython in your project? We use that to allow users to define their own expressions (filters and otherwise) inside a sandbox.
I'm thinking about something like this:
((col1 = "abc") or (col2 = "xyz")) and (col3 = "123")
Ultimately it would be nice to have support for LIKE operator with % wildcard.
Thank you all guys - I've finally found it. It's called NQuery and it's available from CodePlex. In its documentation there is even an example which contains a binding to my very structure - list of column names + list of object[]. Plus fully functional SQL query engine.
Just perfect.

Categories

Resources