Skip to content

Instantly share code, notes, and snippets.

@ToJans
Forked from thecodejunkie/ConNegModule.cs
Created March 3, 2011 09:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ToJans/852551 to your computer and use it in GitHub Desktop.
Save ToJans/852551 to your computer and use it in GitHub Desktop.
The current implementation is a bit ugly, but this could become an easy to use content provider for the NancyFx framework
using System;
using System.Collections;
namespace CG2.FluentContent
{
// note that I currnelty do not have any testing libs or Nancy available
public class ContentProviderSpecs
{
public void A_content_provider_should_respond_to_available_content_types()
{
var SUT = new AContentProviderContext("text/html");
// execution is deferred until the implicit cast to a response is being called
Console.WriteLine((SUT.Example1() as AResponseClass).Content);
Console.WriteLine((SUT.Example2() as AResponseClass).Content);
Console.WriteLine((SUT.Example3() as AResponseClass).Content);
}
}
public class AContentProviderContext
{
ARequestClass req = null;
public AContentProviderContext(string contentType)
{
req = new ARequestClass() { ContentType = contentType };
}
public object Example1()
{
return req.ReplyWith(new { LastName="Janssens",FirstName="Tom",Twitter="Tojans" })
.AsHtml()
.AsJson()
.AsXml().With(m=>"XML blah"+m.ToString())
.As["image/jpg"].With<ABitmapClass>(m=>null)
.As["xyz"].With(m=> m.GetHashCode());
}
public object Example2()
{
return req.ReplyWith(()=> new { LastName="Janssens",FirstName="Tom",Twitter="Tojans" })
.EnableDefaults();
}
public object Example3()
{
return req.ReplyWith(()=> new { LastName="Janssens",FirstName="Tom",Twitter="Tojans" })
.EnableDefaults()
.AsHtmlWithView("Zorro");
}
}
}
using System;
using System.Collections;
namespace CG2.FluentContent
{
public interface IProvideContent<T>
{
IProvideContentType<T> As {get;}
IProvideContent<T> With<TResult>(Func<T, TResult> getReturnVal);
Func<T> GetModel {set;}
}
public interface IProvideContentType<T>
{
IProvideContent<T> this[string contentType] {get;}
}
}
using System;
using System.Collections;
namespace CG2.FluentContent
{
public static class ExtensionMethods
{
public static IProvideContent<T> ReplyWith<T>(this ARequestClass self,T Model)
{
return new ContentProvider<T>(self.ContentType) { GetModel = () => Model };
}
public static IProvideContent<T> ReplyWith<T>(this ARequestClass self,Func<T> GetModel)
{
return new ContentProvider<T>(self.ContentType) { GetModel = GetModel };
}
public static IProvideContent<T> AsHtml<T>(this IProvideContent<T> self)
{
return self.As["text/html"];
}
public static IProvideContent<T> AsHtmlWithView<T>(this IProvideContent<T> self,string viewname)
{
return self.As["text/html"]; // using view xxx
}
public static IProvideContent<T> AsXml<T>(this IProvideContent<T> self)
{
return self.As["text/xml"];
}
public static IProvideContent<T> AsJson<T>(this IProvideContent<T> self)
{
return self.As["text/json"];
}
public static IProvideContent<T> EnableDefaults<T>(this IProvideContent<T> self)
{
return self.AsHtml().AsJson().AsXml();
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
namespace CG2.FluentContent
{
public class ContentProvider<T> : IProvideContent<T>
{
string contentType;
Func<T> getModel = null;
string lastContentType = null;
Dictionary<string,Func<T,object>> Methods = new Dictionary<string, Func<T, object>>();
public ContentProvider(string contentType)
{
this.contentType = contentType;
}
public static implicit operator AResponseClass(ContentProvider<T> inp)
{
var m = inp.getModel();
var res = (inp.Methods[inp.contentType])(m);
return new AResponseClass()
{
Content = m.ToString()
};
}
public IProvideContentType<T> As
{
get { return new ContentProviderType(this);}
}
public Func<T> GetModel {
set
{
getModel = value;
}
}
public IProvideContent<T> With<TResult>(Func<T, TResult> getReturnVal)
{
Methods[lastContentType] = x=>getReturnVal(x) as object;
return this;
}
internal IProvideContent<T> AccessOwner(string contentType)
{
if (!Methods.ContainsKey(contentType))
Methods.Add(contentType,GetDefaultHandler(contentType));
lastContentType = contentType;
return this;
}
protected virtual Func<T, object> GetDefaultHandler(string contenttype)
{
switch(contenttype)
{
// TODO: implement HTML,JSON etc
default: return x => "Default handler for "+contenttype+": "+x.ToString();
}
}
class ContentProviderType : IProvideContentType<T>
{
ContentProvider<T> owner;
public ContentProviderType(ContentProvider<T> owner)
{
this.owner = owner;
}
public IProvideContent<T> this[string contentType] {
get {
return owner.AccessOwner(contentType);
}
}
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
namespace CG2.FluentContent
{
// non nancy avail, so I hacked a bit here
public class ARequestClass { public string ContentType;}
public class ABitmapClass {}
public class AResponseClass { public string Content; };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment