As I am new to C# ,just wish to know, can i perform function chaining in C# like jQuery ?
Example jQuery :
$("#gview tbody tr")
.not(":first,:last")
.filter(":odd")
.addClass("someclass")
.css("border","solid 1px grey");
Note : I don't mean clientside script.My only concern is function chaining is possible in C# or not
Yes, just return the current object (this), and you can chain as much as you want. It's also called fluent interface
Yes you need to look into using the Builder Pattern modified to return the object being worked on.
Example:
public class SomeClass
{
public SomeClass doSomeWork()
{
//do some work on this
this.PropertyA = "Somethign";
return this;
}
}
This is also referred to as a chaining design pattern.
Yes, you can, but as with jQuery, the functions you want to chain must be built for it. If you build your own, just return the object the caller should chain on. One example of chaining in C# is Fluent nHibernate.
Yes. I use it regularly, for example with a StringBuilder:
string s =
new StringBuilder()
.Append(year)
.Append('-')
.Append(month)
.Append('-')
.Append(day)
.ToString();
Or with my own library for creating HTML controls:
Container.Controls.Add(
Tag.Div.CssClass("item")
.AddChild(Tag.Span.CssClass("date").Text(item.Date))
.AddChild(Tag.Span.CssClass("title").Text(item.Title))
);
yes,
try this
var s = 19.ToString().Replace("1"," ").Trim().ToString("0.00");
You can call one function from another just like most programming languages... it all depends on how you build.
You could have an object as such:
public class DoMath
{
private int Add2(int piNumber)
{
return piNumber + 2;
}
private int Divideby7(int piNumber)
{
return Divideby7(this.Add2(piNumber));
}
}
Yes, and there are several good examples of how it can be done. For example, take a look at Fluent NHibernate.
Related
I would like to find a good design pattern on how to implement this example business workflow. Instead of using one giant monolithic procedural-like method call, I was thinking I would like to use a fluent method chaining -- basically, a simple workflow pipeline without using one of those workflow or BPM frameworks. Suggestions on best practice, perhaps a known design pattern?
My Example
get configuration / user preferences
validate config/preferences
look up / standardize additional config/preferences
get report 1 (with above input)
get report 2, etc.
email reports
The inputs/user preferences causes a lot of if/else logic, so I don't want to have my method have to contain all my if/else logic to see if each step was successful or not, and handle. (i.e. I do NOT want)
myOutput1 = CallMethod1(param1, param2, our errorMsg)
if (error)
{ // do something, then break }
myOutput2 = CallMethod2(param1, param2, our errorMsg)
if (error)
{ // do something, then break }
...
myOutput9 = CallMethod9(param1, param2, our errorMsg)
if (error)
{ // do something, then break }
Sample Idea Pipeline code
Perhaps something like this? Would it work? How can I improve upon it?
public class Reporter
{
private ReportSettings Settings {get; set;}
private ReportResponse Response {get; set;}
public ReportResponse GenerateAndSendReports(string groupName)
{
ReportResponse response = this.GetInputConfiguration()
.ValidateConfiguration()
.StandardizeConfiguration(groupName)
.PopulateReport1()
.PopulateReport2()
.PopulateReport99()
.EmailReports()
.Output();
return response;
}
public Reporter GetInputConfiguration()
{
this.Response = new ReportResponse();
this.Settings = new ReportSetting();
this.Settings.IsReport1Enabled = ConfigurationManager.GetSetting("EnableReport1");
this.Settings.Blah1 = ConfigurationManager.GetSetting("Blah1");
this.Settings.Blah2 = ConfigurationManager.GetSetting("Blah2");
return this;
}
public Reporter StandardizeConfiguration(string groupName)
{
this.Settings.Emails = myDataService.GetEmails(groupName);
return this;
}
public Reporter PopulateReport1()
{
if (!this.Setting.HasError && this.Settings.IsReport1Enabled)
{
try
{
this.Response.Report1Content = myReportService.GetReport1(this.Settings.Blah1, this.Blah2)
}
catch (Exception ex)
{
this.Response.HasError = true;
this.Response.Message = ex.ToString();
}
}
return this;
}
}
I was thinking of something like this
You are mentioning two distinct concepts: fluent mechanism, and the pipeline (or chain of responsibility) pattern.
Pipeline Pattern
Must define an interface IPipeline which contains DoThings();.
The implementations of IPipeline must contain an IPipeline GetNext();
Fluent
All actions must return a reference to the object modified by the action: IFluent.
If you which to better control what options are available and when in your workflow, you could have the Fluent actions returning distinct interfaces: for example IValidatedData could expose IStandardizedData Standardize(), and IStandardizedData could expose IStandardizedData PopulateReport(var param) and IStandardizedData PopulateEmail(var param). This is what LINQ does with enumerables, lists, etc.
However, in your example it looks like you are mostly looking for a Fluent mechanism. The pipeline pattern helps with data flows (HTTP request handlers, for example). In your case you are just applying properties to a single object Reporter, so the pipeline pattern does not really apply.
For those who ended here because they are looking for a two-way (push and pull) fluent pipeline, you want your fluent actions to build the pipeline, by returning an IPipelineStep. The behaviour of the pipeline is defined by the implementation of each IPipelineStep.
You can achieve this as follows:
PipelineStep implements IPipelineStep
PipelineStep contains a private IPipelineStep NextStep(get;set);
IPipelineBuilder contains the fluent actions available to build the pipeline.
Your fluent actions return a concretion which implement both IPipelineStep and IPipelineBuilder.
Before returning, the fluent action updates this.NextStep.
IPipelineStep contains a var Push(var input); and var Pull(var input);
Push does things and then calls this.NextStep.Push
Pull calls this.NextStep.Pull and then does things and returns
You also need to consider how you want to use the pipeline once built: from top to bottom or the other way around.
I know this is an old question, but this is a pretty recent video explaining how to build a nice Fluent API. One thing mentioned, that I think is great, is the idea of using interfaces to enforce the correct order to call the APIs.
https://www.youtube.com/watch?v=1JAdZul-aRQ
I have this method in C# that looks like I should really refactor it . Should I use a design pattern ? Too much repetition is what I see NOW and especially as MORE conditional if statements get added
Change to a method?
public void CreateOrUpdateReportDefinition(ReportGroupSubReport reportGroupSubReport, bool isNew, int report)
{
if (report == 1)
{
var entity = _envyUnitOfWork.ReportDefinitions.GetById(reportGroupSubReport.Id) ?? new ReportDefinition();
if (isNew)
entity.SetNew();
_envyUnitOfWork.ReportDefinitions.InsertOrUpdate(entity, true);
}
else if (report == 2)
{
var entity = _envyUnitOfWork.TraxReports.GetById(reportGroupSubReport.Id) ?? new TraxReport();
if (isNew)
entity.SetNew();
_envyUnitOfWork.TraxReports.InsertOrUpdate(entity, true);
}
Mapper.Map(reportGroupSubReport, entity);
_envyUnitOfWork.Commit();
}
So what I would do is to put every single conditional behavior into separate method. To avoid repetition you could use the template method pattern. You should also declare your report variable before all if statements so that it would be accessible for the Mapper.Map().
Edit:
Ok, so assuming that both _envyUnitOfWork.TraxReports and _envyUnitOfWork.ReportDefinitions share some common generic interface (which I named Repository in code) defining GetById and InsertOrUpdate methods, you do not need to use any design patterns - simple generic method will do the job. Here is example of the code:
private void createOrUpdateReportDefinition<Report>(ReportGroupSubReport reportGroupSubReport, bool isNew, Repository<Report> repository/*, Action<Report> insertOrUpdate*/) where Report : new()
{
var entity = repository.GetById(reportGroupSubReport.Id) ?? new Report();
if (isNew)
entity.SetNew();
repository.InsertOrUpdate(entity, true);//insertOrUpdate(entity, true);
Mapper.Map(reportGroupSubReport, entity);
_envyUnitOfWork.Commit();
}
public void CreateOrUpdateReportDefinition(ReportGroupSubReport reportGroupSubReport, bool isNew, int report)
{
if (report == 1)
{
createOrUpdateReportDefinition(reportGroupSubReport, isNew, _envyUnitOfWork.ReportDefinitions/*, _envyUnitOfWork.ReportDefinitions.InsertOrUpdate*/);
}
else if (report == 2)
{
createOrUpdateReportDefinition(reportGroupSubReport, isNew, _envyUnitOfWork.TraxReports/*, _envyUnitOfWork.TraxReports.InsertOrUpdate*/);
}
}
Please take under consideration this code is dealing only with one issue in your code which was the code duplication, there are still few things you could improve like removing int report parameter from the method either by dividing it into few methods or at least by replacing it with some enum with meaningful name. I would also suggest the same (dividing the methods) for the bool isNew parameter, since using it means your function doesn't do one thing only which is against single responsibility principle from SOLID - you can read more about it here.
The following refactoring pattern might give you some clues as to how you could manage the proliferating conditional problem: https://sourcemaking.com/refactoring/replace-conditional-with-polymorphism
Edit: The easiest way to do this would be defining an Interface that both TraxReports and ReportDefinition implement that has a InsertOrUpdate method.
ok, so in javascript, we can declare an object like this,
var obj={name:"Irshu",age:22};
console.log(obj);
How do we do the same in c#? the reason i ask because my function need to return a string and a bool together. I dont want to create a class for it, and i dont want to use the dictionary. Are there any alternatives?
public void Message(){
var obj=GetObject(val);
Messagebox.Show(Convert.ToString(obj.ind));
}
public object GetObject(string val){
return new {ind=val,flag=true};
}
This is not valid, is it?
.Net supports ExpandoObject since .NET 4.
http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject%28v=vs.110%29.aspx
It lets you declare the object and add properties as your would in javascript.
Traditionally it is for JS interop and I can't recommend it for production work. Tuple<T> is more appropriate as you get strong typing for free. Ultimately you will write less code and see less runtime errors.
What you have in your code is an anonymous type. Anonymous types cannot exist outside the scope in which they are declared. Generally, we use these for transforming LINQ results to temporary objects.
You can't return anonymous types from a method. You can do however something like this:
public void Message(){
var obj = new { ind = "oaiwejf", flag = true };
Messagebox.Show(obj.ind);
}
EDIT
Check this MSDN article
turns out, its posible, one genius on the internet posted this:
public void Message()
{
var obj=GetObject("Irshu");
var y= Cast(obj, new { ind= "", flag= true });
Messagebox.Show(y.ind); //alerts Irshu
}
public object GetObject(string val){
return new {ind=val,flag=true};
}
T Cast<T>(object obj, T type)
{
return (T)obj;
}
Maybe this is dreaming, but is it possible to create an attribute that caches the output of a function (say, in HttpRuntime.Cache) and returns the value from the cache instead of actually executing the function when the parameters to the function are the same?
When I say function, I'm talking about any function, whether it fetches data from a DB, whether it adds two integers, or whether it spits out the content of a file. Any function.
Your best bet is Postsharp. I have no idea if they have what you need, but that's certainly worth checking. By the way, make sure to publish the answer here if you find one.
EDIT: also, googling "postsharp caching" gives some links, like this one: Caching with C#, AOP and PostSharp
UPDATE: I recently stumbled upon this article: Introducing Attribute Based Caching. It describes a postsharp-based library on http://cache.codeplex.com/ if you are still looking for a solution.
I have just the same problem - I have multiply expensive methods in my app and it is necessary for me to cache those results. Some time ago I just copy-pasted similar code but then I decided to factor this logic out of my domain.
This is how I did it before:
static List<News> _topNews = null;
static DateTime _topNewsLastUpdateTime = DateTime.MinValue;
const int CacheTime = 5; // In minutes
public IList<News> GetTopNews()
{
if (_topNewsLastUpdateTime.AddMinutes(CacheTime) < DateTime.Now)
{
_topNews = GetList(TopNewsCount);
}
return _topNews;
}
And that is how I can write it now:
public IList<News> GetTopNews()
{
return Cacher.GetFromCache(() => GetList(TopNewsCount));
}
Cacher - is a simple helper class, here it is:
public static class Cacher
{
const int CacheTime = 5; // In minutes
static Dictionary<long, CacheItem> _cachedResults = new Dictionary<long, CacheItem>();
public static T GetFromCache<T>(Func<T> action)
{
long code = action.GetHashCode();
if (!_cachedResults.ContainsKey(code))
{
lock (_cachedResults)
{
if (!_cachedResults.ContainsKey(code))
{
_cachedResults.Add(code, new CacheItem { LastUpdateTime = DateTime.MinValue });
}
}
}
CacheItem item = _cachedResults[code];
if (item.LastUpdateTime.AddMinutes(CacheTime) >= DateTime.Now)
{
return (T)item.Result;
}
T result = action();
_cachedResults[code] = new CacheItem
{
LastUpdateTime = DateTime.Now,
Result = result
};
return result;
}
}
class CacheItem
{
public DateTime LastUpdateTime { get; set; }
public object Result { get; set; }
}
A few words about Cacher. You might notice that I don't use Monitor.Enter() ( lock(...) ) while computing results. It's because copying CacheItem pointer ( return (T)_cachedResults[code].Result; line) is thread safe operation - it is performed by only one stroke. Also it is ok if more than one thread will change this pointer at the same time - they all will be valid.
You could add a dictionary to your class using a comma separated string including the function name as the key, and the result as the value. Then when your functions can check the dictionary for the existence of that value. Save the dictionary in the cache so that it exists for all users.
PostSharp is your one stop shop for this if you want to create a [Cache] attribute (or similar) that you can stick on any method anywhere. Previously when I used PostSharp I could never get past how slow it made my builds (this was back in 2007ish, so this might not be relevant anymore).
An alternate solution is to look into using Render.Partial with ASP.NET MVC in combination with OutputCaching. This is a great solution for serving html for widgets / page regions.
Another solution that would be with MVC would be to implement your [Cache] attribute as an ActionFilterAttribute. This would allow you to take a controller method and tag it to be cached. It would only work for controller methods since the AOP magic only can occur with the ActionFilterAttributes during the MVC pipeline.
Implementing AOP through ActionFilterAttribute has evolved to be the goto solution for my shop.
AFAIK, frankly, no.
But this would be quite an undertaking to implement within the framework in order for it to work generically for everybody in all circumstances, anyway - you could, however, tailor something quite sufficient to needs by simply (where simplicity is relative to needs, obviously) using abstraction, inheritance and the existing ASP.NET Cache.
If you don't need attribute configuration but accept code configuration, maybe MbCache is what you're looking for?
I just started using C# this afternoon, so be a little gentle.
Currently I am working on a type of "template engine" where one of the callbacks needs to generate a globally unique ID. I am using delegates to manage the callbacks.
Currently the code looks like this (though I have also tried an anonymous function & returning NewGuid directly w/o a variable):
static string UID(List<string> p)
{
string s = Guid.NewGuid().ToString();
return s;
}
Which, when called directly, works fine. However if I try to call it via the delegate (added to a StringDictionary via addCallback("generate UID", new CallbackWrapper(UID))), the program will generate the same GUID regardless of how many times I duplicate it; even though calling the method directly both before & after the event occurs results in a unique ID as expected. I'v
No doubt it's just something simple I've missed, inevitably stemming from me being relatively inexperienced at C#.
Any help would be appreciated.
Thanks.
Well, I've now tried Dictionary with the same result.
CallbackWrapper is just the delegate, it's defined like this:
delegate string CallbackWrapper(List<string> parameters);
The remainder of the work is done in another class, which looks like this:
class TemplateParser
{
private Dictionary<string, CallbackWrapper> callbackMap;
public TemplateParser(string directivePrefix, string directiveSuffix)
{
...
callbackMap = new Dictionary<string,CallbackWrapper>();
}
public TemplateParser() : this("<!-- {", "} -->") {}
{
callbackMap.Add(name, callback);
}
public string parse(string filename)
{
...
string replacement =
callbackMap[directiveName](new List<string>(parameters.Split(new string[] { ";", " " }, StringSplitOptions.RemoveEmptyEntries));
...
}
}
I've stripped out the majority of the string handling code to save some space.
The issue is in your calling code, not in the code itself, nor in the delegate.
Using delegates here definitely works if called correctly.
Furthermore, your code can be slightly simplified:
static string UID(List<string> p)
{
return Guid.NewGuid().ToString();
}
(The variable is utterly redundant.)
use delegate.invoke
The difference between direct function call and delegate.invoke is here
http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/f629c34d-6523-433a-90b3-bb5d445c5587
StringDictionary will automatically cast your CallbackWrapper to a string, meaning it will only run once and store the output of CallbackWrapper.ToString(). This is probably not what you want.
Try using Dictionary<string, CallbackWrapper> instead.