<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel><title>Gut Instinct</title>
<link>http://www.gutgames.com/</link>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="self" href="http://www.gutgames.com/" type="application/rss+xml" /><description><![CDATA[Gut Instinct]]></description>
<language>en-us</language>
<copyright>Copyright 2021</copyright>
<webMaster></webMaster>
<pubDate>D05, 05 May 2021 12:47:21</pubDate>
<itunes:explicit>no</itunes:explicit><itunes:subtitle>Gut Instinct</itunes:subtitle><itunes:summary><![CDATA[Gut Instinct]]></itunes:summary><docs>http://blogs.law.harvard.edu/tech/rss</docs>
<ttl>5</ttl>
<item><title>Craigandrsquo;s Utility Library 3.2 Released</title>
<link>http://www.gutgames.com/post/Craigrsquo3bs-Utility-Library-32-Released.aspx</link>
<author>James Craig</author>
<pubDate>Mon, 03 Sep 2012 16:20:59 GMT</pubDate>
<description><![CDATA[A new version (3.2) of Craig’s Utility Library has been released. It’s not a huge release but it adds a number of fixes, speed increases, and methods to make your life a bit easier. However there was one major addition with regard to randomization. This time a much more robust set of classes and extension methods dealing with randomization. It adds the ability to randomly generate company names, male/female names, cities, states, zip codes, phone numbers, even entire data classes by simply calling either the Nextandlt;Tandgt;(...) or NextClassandlt;Tandgt;(...) extension methods that were added. In fact the Next generic extension method has built in generators for bool, decimal, double, float, byte, char, int, long, sbyte, short, uint, ulong, ushort, DateTime, TimeSpan, Color, and string (with a ton of other string generators). In fact with the new classes and extension methods you can do something like this:             1: public class RandomTestClass<br /><br /><br />       2: {<br /><br /><br />       3:     [IntGenerator]<br /><br /><br />       4:     public int A { get; set; }<br /><br /><br />       5: <br /><br /><br />       6:     [LoremIpsumGenerator]<br /><br /><br />       7:     public string B { get; set; }<br /><br /><br />       8: <br /><br /><br />       9:     [FloatGenerator]<br /><br /><br />      10:     public float C { get; set; }<br /><br /><br />      11: <br /><br /><br />      12:     [IntGenerator(1, 100)]<br /><br /><br />      13:     public int D { get; set; }<br /><br /><br />      14: }<br /><br /><br /><br /><br /><br />And call NextClass and have a newly generated RandomTestClass object given to you.<br /><br />Past the new randomization classes/extension methods, a number of updates, speed increases, and fixes were implemented on the SQLHelper, MicroORM, and ORM classes. For example, you can now add parameters in batch to the SQLHelper class by simply calling the AddParameter function. (For example if you have andquot;SELECT * FROM Table WHERE ID=@0 and Value=@1andquot; and you used AddParameter(10, andquot;This is a stringandquot;) then it would put the value 10 in for @0 and andquot;This is a stringandquot; for @1 (note that it would do that as a parameter, it doesn't do string concat).<br /><br />On top of that a number of extensions to make life easier were added, such as Times which will run a function/action the specified number of times, so 100.Times(x=andgt;x) creates a list of integers going from 1 to 100. On top of that, I ‘ve added:<br /><br /><br />  A RingBuffer class<br /><br />  Google API class for pulling static maps<br /><br />  LevenshteinDistance extension for strings<br /><br />  extension method to convert Dictionary and NameValueCollections classes to query strings<br /><br />  UserIPAddress and IfModifiedSince extension methods for HttpRequest<br /><br />  RelativeTime extension which expresses the difference between a DateTime and some Epoch as a string<br /><br />  updated the BlogML code to allow exporting<br /><br />  added ReadAll and ReadAllBinary extensions for Stream objects<br /><br />  and a number of other items.<br /><br /><br />Future of the Library<br /><br />I’ve recently had a number of requests for additions as well as a couple other questions regarding 3rd party libraries. With regard to 3rd party libraries, I'm at a bit of a cross roads at the moment. When I started the library I wanted to make it so that it only relied on .Net and maybe a couple Win32/COM APIs. There were a couple of reasons for not using 3rd party libraries. I mean part of the issue was the fact this library is sort of a learning experience for me. When I want to try out a concept, I usually do it here. Hence I have no desire to use something like AForge for simple image manipulation. I want to build that myself to learn about the subject. But the main reason for not using 3rd party libraries was that at the time, it was a pain.<br /><br />Keeping libraries updated and working between updates took a lot of work, requiring users to pin to a specific version of a library was difficult, putting out updates of your product became a pain, etc. Now we have NuGet. NuGet makes all of those issues simple to handle (and I don't think I would lose any users as I actually get more downloads from there than Codeplex at this point). On top of that we're now in a weird bizarro world where the .Net guys (well the web portion anyway) are now using open source libraries...<br /><br />So let's assume I say OK to the 3rd party libraries, what libraries? Because not only is Json.Net a possibility (and it's MIT license, so that works), but ServiceStack has some advantages. Then you have other libraries that are getting added into the andquot;blessedandquot; mix (DotNetOpenAuth, etc), which is probably only going to expand in the future... But then does it even matter if something gets the nod from Microsoft? Personally I say no. I tend to remove all of their prepackaged libraries and start from scratch anyway. That being said, I actually do use Json.Net, but I can’t guarantee that I will continue to do so in the future. In fact I tend to swap out libraries without giving it a second thought…<br /><br />Anyway, long story short, I’m not going to be adding 3rd party libraries directly into the library. However I am looking at ways to allow people to attach 3rd party libraries to the system. It will probably be some combination of MEF, IoC, and extension points. I’m still working on the design though. As far as requests for additions, I welcome people to fork the library and make additions. However most changes that I make are due to my day to day work so if it’s in line with what I’m already doing, I’ll probably add it. If it’s not, it might take a while for me to add it. But if you fork the project and make additions, I’ll most likely accept them.]]></description>
<itunes:subtitle>Craigandrsquo;s Utility Library 3.2 Released</itunes:subtitle><itunes:summary><![CDATA[A new version (3.2) of Craig’s Utility Library has been released. It’s not a huge release but it adds a number of fixes, speed increases, and methods to make your life a bit easier. However there was one major addition with regard to randomization. This time a much more robust set of classes and extension methods dealing with randomization. It adds the ability to randomly generate company names, male/female names, cities, states, zip codes, phone numbers, even entire data classes by simply calling either the Nextandlt;Tandgt;(...) or NextClassandlt;Tandgt;(...) extension methods that were added. In fact the Next generic extension method has built in generators for bool, decimal, double, float, byte, char, int, long, sbyte, short, uint, ulong, ushort, DateTime, TimeSpan, Color, and string (with a ton of other string generators). In fact with the new classes and extension methods you can do something like this:             1: public class RandomTestClass<br /><br /><br />       2: {<br /><br /><br />       3:     [IntGenerator]<br /><br /><br />       4:     public int A { get; set; }<br /><br /><br />       5: <br /><br /><br />       6:     [LoremIpsumGenerator]<br /><br /><br />       7:     public string B { get; set; }<br /><br /><br />       8: <br /><br /><br />       9:     [FloatGenerator]<br /><br /><br />      10:     public float C { get; set; }<br /><br /><br />      11: <br /><br /><br />      12:     [IntGenerator(1, 100)]<br /><br /><br />      13:     public int D { get; set; }<br /><br /><br />      14: }<br /><br /><br /><br /><br /><br />And call NextClass and have a newly generated RandomTestClass object given to you.<br /><br />Past the new randomization classes/extension methods, a number of updates, speed increases, and fixes were implemented on the SQLHelper, MicroORM, and ORM classes. For example, you can now add parameters in batch to the SQLHelper class by simply calling the AddParameter function. (For example if you have andquot;SELECT * FROM Table WHERE ID=@0 and Value=@1andquot; and you used AddParameter(10, andquot;This is a stringandquot;) then it would put the value 10 in for @0 and andquot;This is a stringandquot; for @1 (note that it would do that as a parameter, it doesn't do string concat).<br /><br />On top of that a number of extensions to make life easier were added, such as Times which will run a function/action the specified number of times, so 100.Times(x=andgt;x) creates a list of integers going from 1 to 100. On top of that, I ‘ve added:<br /><br /><br />  A RingBuffer class<br /><br />  Google API class for pulling static maps<br /><br />  LevenshteinDistance extension for strings<br /><br />  extension method to convert Dictionary and NameValueCollections classes to query strings<br /><br />  UserIPAddress and IfModifiedSince extension methods for HttpRequest<br /><br />  RelativeTime extension which expresses the difference between a DateTime and some Epoch as a string<br /><br />  updated the BlogML code to allow exporting<br /><br />  added ReadAll and ReadAllBinary extensions for Stream objects<br /><br />  and a number of other items.<br /><br /><br />Future of the Library<br /><br />I’ve recently had a number of requests for additions as well as a couple other questions regarding 3rd party libraries. With regard to 3rd party libraries, I'm at a bit of a cross roads at the moment. When I started the library I wanted to make it so that it only relied on .Net and maybe a couple Win32/COM APIs. There were a couple of reasons for not using 3rd party libraries. I mean part of the issue was the fact this library is sort of a learning experience for me. When I want to try out a concept, I usually do it here. Hence I have no desire to use something like AForge for simple image manipulation. I want to build that myself to learn about the subject. But the main reason for not using 3rd party libraries was that at the time, it was a pain.<br /><br />Keeping libraries updated and working between updates took a lot of work, requiring users to pin to a specific version of a library was difficult, putting out updates of your product became a pain, etc. Now we have NuGet. NuGet makes all of those issues simple to handle (and I don't think I would lose any users as I actually get more downloads from there than Codeplex at this point). On top of that we're now in a weird bizarro world where the .Net guys (well the web portion anyway) are now using open source libraries...<br /><br />So let's assume I say OK to the 3rd party libraries, what libraries? Because not only is Json.Net a possibility (and it's MIT license, so that works), but ServiceStack has some advantages. Then you have other libraries that are getting added into the andquot;blessedandquot; mix (DotNetOpenAuth, etc), which is probably only going to expand in the future... But then does it even matter if something gets the nod from Microsoft? Personally I say no. I tend to remove all of their prepackaged libraries and start from scratch anyway. That being said, I actually do use Json.Net, but I can’t guarantee that I will continue to do so in the future. In fact I tend to swap out libraries without giving it a second thought…<br /><br />Anyway, long story short, I’m not going to be adding 3rd party libraries directly into the library. However I am looking at ways to allow people to attach 3rd party libraries to the system. It will probably be some combination of MEF, IoC, and extension points. I’m still working on the design though. As far as requests for additions, I welcome people to fork the library and make additions. However most changes that I make are due to my day to day work so if it’s in line with what I’m already doing, I’ll probably add it. If it’s not, it might take a while for me to add it. But if you fork the project and make additions, I’ll most likely accept them.]]></itunes:summary></item>
<item><title>Craigandrsquo;s Framework</title>
<link>http://www.gutgames.com/post/Craigrsquo3bs-Framework.aspx</link>
<author>James Craig</author>
<pubDate>Sun, 20 May 2012 15:38:54 GMT</pubDate>
<description><![CDATA[For the past two weeks I’ve been working on a project that I mentioned here. Basically what I want to ultimately do is create a system that combines my data from various sources into one location so I can easily access it. Depending, at least with some of the items, I may simply develop a replacement that better suits my needs but much of it is going to be simply calling 3rd party APIs. So for two weeks (in the little spare time that I’ve had), I’ve been setting the foundation that I’m going to use to build the system. This is a rather simple process for me, because for the past three years or so, I’ve had a basic framework that I put together to simplify my development process. This time around though I need to make some modifications to it (it was aimed at web forms and this time around I’m using MVC for the project) and since I’m making modifications anyway, I figured I might as well make it open source (similar to my utility library).  Unlike my utility library, this is going to include a number of 3rd party libraries (Json.Net, etc). As such it’s going to be a bit more opinionated and a little less open than the utility library. Also it’s being retooled to be aimed more at a single page style application (not using the SPA template that’s going to be coming out in MVC 4). So it might not be as useful to everyone else and simply be a public NuGet package that I use myself… Anyway, it still needs a bit of work but I might as well show a bit of code:             1: /// andlt;summaryandgt;<br /><br /><br />       2: /// Sets the content type<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]<br /><br /><br />       5: public class ContentType : ActionFilterAttribute<br /><br /><br />       6: {<br /><br /><br />       7:     #region Properties<br /><br /><br />       8: <br /><br /><br />       9:     /// andlt;summaryandgt;<br /><br /><br />      10:     /// Content type to set for this item<br /><br /><br />      11:     /// andlt;/summaryandgt;<br /><br /><br />      12:     public virtual string Type { get; set; }<br /><br /><br />      13: <br /><br /><br />      14:     #endregion<br /><br /><br />      15: <br /><br /><br />      16:     #region Functions<br /><br /><br />      17: <br /><br /><br />      18:     /// andlt;summaryandgt;<br /><br /><br />      19:     /// OnActionExecuted<br /><br /><br />      20:     /// andlt;/summaryandgt;<br /><br /><br />      21:     /// andlt;param name=andquot;filterContextandquot;andgt;filter contextandlt;/paramandgt;<br /><br /><br />      22:     public override void OnActionExecuted(ActionExecutedContext filterContext)<br /><br /><br />      23:     {<br /><br /><br />      24:         filterContext.HttpContext.Response.ContentType = Type;<br /><br /><br />      25:         base.OnActionExecuted(filterContext);<br /><br /><br />      26:     }<br /><br /><br />      27: <br /><br /><br />      28: <br /><br /><br />      29:     #endregion<br /><br /><br />      30: }<br /><br /><br /><br />Many of the classes in the framework are simply helper classes, like the one above. So, for instance, above is an ActionFilter that simply lets me place an attribute on a class so I can set the ContentType that will be returned. I have others that force all requests be forced over to SSL, one that adds a variable to a controller saying what the HTTP verb is, one that tells the client to cache the content that it receives, etc. These sorts of classes probably comprise about 50% of what’s in there at present. The other half is base classes. For instance, I have two base classes for controllers. The first is aimed at APIs and controllers that will mostly be dealing with JSON:<br /><br /><br />  <br />       1: /// andlt;summaryandgt;<br /><br /><br />       2: /// API Controller base class<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: [ContentType(Type = andquot;application/jsonandquot;)]<br /><br /><br />       5: public class APIControllerBase : System.Web.Mvc.Controller<br /><br /><br />       6: {<br /><br /><br />       7:     /// andlt;summaryandgt;<br /><br /><br />       8:     /// Encoding used for the controller (defaults to UTF8)<br /><br /><br />       9:     /// andlt;/summaryandgt;<br /><br /><br />      10:     public virtual Encoding Encoding { get; set; }<br /><br /><br />      11: <br /><br /><br />      12:     /// andlt;summaryandgt;<br /><br /><br />      13:     /// Initializes the controller<br /><br /><br />      14:     /// andlt;/summaryandgt;<br /><br /><br />      15:     /// andlt;param name=andquot;requestContextandquot;andgt;Request contextandlt;/paramandgt;<br /><br /><br />      16:     protected override void Initialize(System.Web.Routing.RequestContext requestContext)<br /><br /><br />      17:     {<br /><br /><br />      18:         requestContext.HttpContext.HTTPCompress();<br /><br /><br />      19:         requestContext.HttpContext.Response.ContentEncoding = Encoding.NullCheck(new UTF8Encoding());<br /><br /><br />      20:         base.Initialize(requestContext);<br /><br /><br />      21:     }<br /><br /><br />      22: <br /><br /><br />      23:     /// andlt;summaryandgt;<br /><br /><br />      24:     /// Returns Json encoded object<br /><br /><br />      25:     /// andlt;/summaryandgt;<br /><br /><br />      26:     /// andlt;param name=andquot;Objectandquot;andgt;Object to encodeandlt;/paramandgt;<br /><br /><br />      27:     /// andlt;returnsandgt;The object as a Json.Net resultandlt;/returnsandgt;<br /><br /><br />      28:     protected virtual JsonNetResult JsonNet(object Object)<br /><br /><br />      29:     {<br /><br /><br />      30:         JsonNetResult Result = null;<br /><br /><br />      31:         JsonSerializerSettings Settings = new JsonSerializerSettings();<br /><br /><br />      32:         IsoDateTimeConverter Converter = new IsoDateTimeConverter();<br /><br /><br />      33:         Settings.Converters.Add(Converter);<br /><br /><br />      34:         Result = new JsonNetResult(Object, Settings, Formatting.None);<br /><br /><br />      35:         return Result;<br /><br /><br />      36:     }<br /><br /><br />      37: <br /><br /><br />      38:     /// andlt;summaryandgt;<br /><br /><br />      39:     /// On Action Executed<br /><br /><br />      40:     /// andlt;/summaryandgt;<br /><br /><br />      41:     /// andlt;param name=andquot;filterContextandquot;andgt;filter contextandlt;/paramandgt;<br /><br /><br />      42:     protected override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext)<br /><br /><br />      43:     {<br /><br /><br />      44:         base.OnActionExecuted(filterContext);<br /><br /><br />      45:     }<br /><br /><br />      46: }<br /><br /><br /><br /><br /><br />I’m still adding to it, but at present it compresses the data sent back (using GZip by default), sets the encoding, sets the content type to ‘application/json’ and adds a function JsonNet that serializes an object to JSON (using Json.Net) and returns it as a result. The other controller base class deals primarily with controllers that deal primarily with HTML:<br /><br /><br />  <br />       1: /// andlt;summaryandgt;<br /><br /><br />       2: /// Base class for controllers<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: [CSRF]<br /><br /><br />       5: public class ControllerBase : System.Web.Mvc.Controller<br /><br /><br />       6: {<br /><br /><br />       7:     /// andlt;summaryandgt;<br /><br /><br />       8:     /// Encoding used for the controller (defaults to UTF8)<br /><br /><br />       9:     /// andlt;/summaryandgt;<br /><br /><br />      10:     public virtual Encoding Encoding { get; set; }<br /><br /><br />      11: <br /><br /><br />      12:     /// andlt;summaryandgt;<br /><br /><br />      13:     /// Initializes the controller<br /><br /><br />      14:     /// andlt;/summaryandgt;<br /><br /><br />      15:     /// andlt;param name=andquot;requestContextandquot;andgt;Request contextandlt;/paramandgt;<br /><br /><br />      16:     protected override void Initialize(System.Web.Routing.RequestContext requestContext)<br /><br /><br />      17:     {<br /><br /><br />      18:         requestContext.HttpContext.HTTPCompress(true);<br /><br /><br />      19:         requestContext.HttpContext.Response.ContentEncoding = Encoding.NullCheck(new UTF8Encoding());<br /><br /><br />      20:         base.Initialize(requestContext);<br /><br /><br />      21:     }<br /><br /><br />      22: <br /><br /><br />      23:     /// andlt;summaryandgt;<br /><br /><br />      24:     /// On Action Executed<br /><br /><br />      25:     /// andlt;/summaryandgt;<br /><br /><br />      26:     /// andlt;param name=andquot;filterContextandquot;andgt;filter contextandlt;/paramandgt;<br /><br /><br />      27:     protected override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext)<br /><br /><br />      28:     {<br /><br /><br />      29:         base.OnActionExecuted(filterContext);<br /><br /><br />      30:     }<br /><br /><br />      31: }<br /><br /><br /><br /><br />This one, using a couple of functions from my utility library, compresses the data sent back and removes white space (basically removes “pretty printing”), sets the encoding, and adds a cross site request forgery token on any form (that’s the CSRF attribute on the class). Past that, there are classes that help add themes to MVC, automatically compress CSS and Javascript files, classes that will help with plugins, etc. In fact, my ultimate goal with this framework is to make it so that once I drop it in place, all I have to do is define my models and it will set up my REST API and services for me so all I need to do is the HTML, CSS, Javascript, etc. basically the front end stuff (minus the one off items). Anyway, I’m hoping to have this done soon so I can put it up on CodePlex/Github with an initial release and then start on the main project. So I’ll keep people posted and happy coding.]]></description>
<itunes:subtitle>Craigandrsquo;s Framework</itunes:subtitle><itunes:summary><![CDATA[For the past two weeks I’ve been working on a project that I mentioned here. Basically what I want to ultimately do is create a system that combines my data from various sources into one location so I can easily access it. Depending, at least with some of the items, I may simply develop a replacement that better suits my needs but much of it is going to be simply calling 3rd party APIs. So for two weeks (in the little spare time that I’ve had), I’ve been setting the foundation that I’m going to use to build the system. This is a rather simple process for me, because for the past three years or so, I’ve had a basic framework that I put together to simplify my development process. This time around though I need to make some modifications to it (it was aimed at web forms and this time around I’m using MVC for the project) and since I’m making modifications anyway, I figured I might as well make it open source (similar to my utility library).  Unlike my utility library, this is going to include a number of 3rd party libraries (Json.Net, etc). As such it’s going to be a bit more opinionated and a little less open than the utility library. Also it’s being retooled to be aimed more at a single page style application (not using the SPA template that’s going to be coming out in MVC 4). So it might not be as useful to everyone else and simply be a public NuGet package that I use myself… Anyway, it still needs a bit of work but I might as well show a bit of code:             1: /// andlt;summaryandgt;<br /><br /><br />       2: /// Sets the content type<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]<br /><br /><br />       5: public class ContentType : ActionFilterAttribute<br /><br /><br />       6: {<br /><br /><br />       7:     #region Properties<br /><br /><br />       8: <br /><br /><br />       9:     /// andlt;summaryandgt;<br /><br /><br />      10:     /// Content type to set for this item<br /><br /><br />      11:     /// andlt;/summaryandgt;<br /><br /><br />      12:     public virtual string Type { get; set; }<br /><br /><br />      13: <br /><br /><br />      14:     #endregion<br /><br /><br />      15: <br /><br /><br />      16:     #region Functions<br /><br /><br />      17: <br /><br /><br />      18:     /// andlt;summaryandgt;<br /><br /><br />      19:     /// OnActionExecuted<br /><br /><br />      20:     /// andlt;/summaryandgt;<br /><br /><br />      21:     /// andlt;param name=andquot;filterContextandquot;andgt;filter contextandlt;/paramandgt;<br /><br /><br />      22:     public override void OnActionExecuted(ActionExecutedContext filterContext)<br /><br /><br />      23:     {<br /><br /><br />      24:         filterContext.HttpContext.Response.ContentType = Type;<br /><br /><br />      25:         base.OnActionExecuted(filterContext);<br /><br /><br />      26:     }<br /><br /><br />      27: <br /><br /><br />      28: <br /><br /><br />      29:     #endregion<br /><br /><br />      30: }<br /><br /><br /><br />Many of the classes in the framework are simply helper classes, like the one above. So, for instance, above is an ActionFilter that simply lets me place an attribute on a class so I can set the ContentType that will be returned. I have others that force all requests be forced over to SSL, one that adds a variable to a controller saying what the HTTP verb is, one that tells the client to cache the content that it receives, etc. These sorts of classes probably comprise about 50% of what’s in there at present. The other half is base classes. For instance, I have two base classes for controllers. The first is aimed at APIs and controllers that will mostly be dealing with JSON:<br /><br /><br />  <br />       1: /// andlt;summaryandgt;<br /><br /><br />       2: /// API Controller base class<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: [ContentType(Type = andquot;application/jsonandquot;)]<br /><br /><br />       5: public class APIControllerBase : System.Web.Mvc.Controller<br /><br /><br />       6: {<br /><br /><br />       7:     /// andlt;summaryandgt;<br /><br /><br />       8:     /// Encoding used for the controller (defaults to UTF8)<br /><br /><br />       9:     /// andlt;/summaryandgt;<br /><br /><br />      10:     public virtual Encoding Encoding { get; set; }<br /><br /><br />      11: <br /><br /><br />      12:     /// andlt;summaryandgt;<br /><br /><br />      13:     /// Initializes the controller<br /><br /><br />      14:     /// andlt;/summaryandgt;<br /><br /><br />      15:     /// andlt;param name=andquot;requestContextandquot;andgt;Request contextandlt;/paramandgt;<br /><br /><br />      16:     protected override void Initialize(System.Web.Routing.RequestContext requestContext)<br /><br /><br />      17:     {<br /><br /><br />      18:         requestContext.HttpContext.HTTPCompress();<br /><br /><br />      19:         requestContext.HttpContext.Response.ContentEncoding = Encoding.NullCheck(new UTF8Encoding());<br /><br /><br />      20:         base.Initialize(requestContext);<br /><br /><br />      21:     }<br /><br /><br />      22: <br /><br /><br />      23:     /// andlt;summaryandgt;<br /><br /><br />      24:     /// Returns Json encoded object<br /><br /><br />      25:     /// andlt;/summaryandgt;<br /><br /><br />      26:     /// andlt;param name=andquot;Objectandquot;andgt;Object to encodeandlt;/paramandgt;<br /><br /><br />      27:     /// andlt;returnsandgt;The object as a Json.Net resultandlt;/returnsandgt;<br /><br /><br />      28:     protected virtual JsonNetResult JsonNet(object Object)<br /><br /><br />      29:     {<br /><br /><br />      30:         JsonNetResult Result = null;<br /><br /><br />      31:         JsonSerializerSettings Settings = new JsonSerializerSettings();<br /><br /><br />      32:         IsoDateTimeConverter Converter = new IsoDateTimeConverter();<br /><br /><br />      33:         Settings.Converters.Add(Converter);<br /><br /><br />      34:         Result = new JsonNetResult(Object, Settings, Formatting.None);<br /><br /><br />      35:         return Result;<br /><br /><br />      36:     }<br /><br /><br />      37: <br /><br /><br />      38:     /// andlt;summaryandgt;<br /><br /><br />      39:     /// On Action Executed<br /><br /><br />      40:     /// andlt;/summaryandgt;<br /><br /><br />      41:     /// andlt;param name=andquot;filterContextandquot;andgt;filter contextandlt;/paramandgt;<br /><br /><br />      42:     protected override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext)<br /><br /><br />      43:     {<br /><br /><br />      44:         base.OnActionExecuted(filterContext);<br /><br /><br />      45:     }<br /><br /><br />      46: }<br /><br /><br /><br /><br /><br />I’m still adding to it, but at present it compresses the data sent back (using GZip by default), sets the encoding, sets the content type to ‘application/json’ and adds a function JsonNet that serializes an object to JSON (using Json.Net) and returns it as a result. The other controller base class deals primarily with controllers that deal primarily with HTML:<br /><br /><br />  <br />       1: /// andlt;summaryandgt;<br /><br /><br />       2: /// Base class for controllers<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: [CSRF]<br /><br /><br />       5: public class ControllerBase : System.Web.Mvc.Controller<br /><br /><br />       6: {<br /><br /><br />       7:     /// andlt;summaryandgt;<br /><br /><br />       8:     /// Encoding used for the controller (defaults to UTF8)<br /><br /><br />       9:     /// andlt;/summaryandgt;<br /><br /><br />      10:     public virtual Encoding Encoding { get; set; }<br /><br /><br />      11: <br /><br /><br />      12:     /// andlt;summaryandgt;<br /><br /><br />      13:     /// Initializes the controller<br /><br /><br />      14:     /// andlt;/summaryandgt;<br /><br /><br />      15:     /// andlt;param name=andquot;requestContextandquot;andgt;Request contextandlt;/paramandgt;<br /><br /><br />      16:     protected override void Initialize(System.Web.Routing.RequestContext requestContext)<br /><br /><br />      17:     {<br /><br /><br />      18:         requestContext.HttpContext.HTTPCompress(true);<br /><br /><br />      19:         requestContext.HttpContext.Response.ContentEncoding = Encoding.NullCheck(new UTF8Encoding());<br /><br /><br />      20:         base.Initialize(requestContext);<br /><br /><br />      21:     }<br /><br /><br />      22: <br /><br /><br />      23:     /// andlt;summaryandgt;<br /><br /><br />      24:     /// On Action Executed<br /><br /><br />      25:     /// andlt;/summaryandgt;<br /><br /><br />      26:     /// andlt;param name=andquot;filterContextandquot;andgt;filter contextandlt;/paramandgt;<br /><br /><br />      27:     protected override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext)<br /><br /><br />      28:     {<br /><br /><br />      29:         base.OnActionExecuted(filterContext);<br /><br /><br />      30:     }<br /><br /><br />      31: }<br /><br /><br /><br /><br />This one, using a couple of functions from my utility library, compresses the data sent back and removes white space (basically removes “pretty printing”), sets the encoding, and adds a cross site request forgery token on any form (that’s the CSRF attribute on the class). Past that, there are classes that help add themes to MVC, automatically compress CSS and Javascript files, classes that will help with plugins, etc. In fact, my ultimate goal with this framework is to make it so that once I drop it in place, all I have to do is define my models and it will set up my REST API and services for me so all I need to do is the HTML, CSS, Javascript, etc. basically the front end stuff (minus the one off items). Anyway, I’m hoping to have this done soon so I can put it up on CodePlex/Github with an initial release and then start on the main project. So I’ll keep people posted and happy coding.]]></itunes:summary></item>
<item><title>Personal Data Management</title>
<link>http://www.gutgames.com/post/Personal-Data-Management.aspx</link>
<author>James Craig</author>
<pubDate>Sun, 06 May 2012 21:06:16 GMT</pubDate>
<description><![CDATA[As of late, I’ve been working on a couple of projects. The first of which was my utility library. I went through Python and Ruby standard libraries (and Rails) for ideas to pull over. It was interesting to see where each item put its focus and trying to add something similar to C#. The other project that I’ve been working on was a mixture of CRM, invoicing, and a couple of other things aimed at a small law firm (tried a number of other 3rd party products but they couldn’t find anything they liked so they wanted something custom). That I can’t release, interesting to build but it’s never going to see the light of day outside the one law firm. Anyway, the combination of the two has kept me from doing anything interesting that I can talk about…  However for the past week I’ve had some free time. When I have free time, I get bored. When I get bored, I start getting annoyed at something or other. In this case, I’ve been annoyed at the fact that I have about 30 websites and apps that I routinely go to and use. In fact a much larger portion of my day than I would like is spent going to them in order to get things done. Then there is the fact that my data is in 30 different locations (well actually about 20 different locations), none of which is talking to one another. So I figured I would try to fix it, so I started with requirements. Generally speaking my stuff can be divided into the following categories:     Task manager (I’m a strong believer in checklists)    Contact manager    File manager    Time tracker (in fact I like to keep track of a number of metrics for myself)    Text editor/IDEs (Visual Studio, NotePad++, etc.)    Formatted documents (Word), spreadsheets, etc. (basically work documents that need to be “pretty”)    Bug tracker    Build server    Source control    Email    Calendar    Notes    Photo editing/management    RSS feeds    Code documentation    FTP    Database management    Entertainment (music, movies, games, comics)   There is probably more but that’s what I could think of in a couple minutes this morning. So there are items like Zoho that can handle the tasks, contacts, etc. But they’re really all separate apps. My data is in one location, but not what I would consider convenient. On top of that I can’t really tie in any of my code stuff, the entertainment items, etc. Google has a number of these items but at present it’s still 10 separate apps that I have to switch between, so better but not great. I even looked into some web based OSes (eyeOS, etc). Once again, not bad but it’s still mostly a system where I have to switch between 20 or so apps that just run on the OS… So basically I couldn’t find anything really and thus I’ve come to the conclusion that I need to build it.  I’m not sure if I’m going to open source the project completely because I’m not sure how helpful it would be to anyone other than myself. That being said, I figured I would share my progress, give snippets of code, etc. Anything that might be of interest and code that could be useful. But for now I’m in the planning stage, so give me a week and I’ll have more to share. Anyway, happy coding.]]></description>
<itunes:subtitle>Personal Data Management</itunes:subtitle><itunes:summary><![CDATA[As of late, I’ve been working on a couple of projects. The first of which was my utility library. I went through Python and Ruby standard libraries (and Rails) for ideas to pull over. It was interesting to see where each item put its focus and trying to add something similar to C#. The other project that I’ve been working on was a mixture of CRM, invoicing, and a couple of other things aimed at a small law firm (tried a number of other 3rd party products but they couldn’t find anything they liked so they wanted something custom). That I can’t release, interesting to build but it’s never going to see the light of day outside the one law firm. Anyway, the combination of the two has kept me from doing anything interesting that I can talk about…  However for the past week I’ve had some free time. When I have free time, I get bored. When I get bored, I start getting annoyed at something or other. In this case, I’ve been annoyed at the fact that I have about 30 websites and apps that I routinely go to and use. In fact a much larger portion of my day than I would like is spent going to them in order to get things done. Then there is the fact that my data is in 30 different locations (well actually about 20 different locations), none of which is talking to one another. So I figured I would try to fix it, so I started with requirements. Generally speaking my stuff can be divided into the following categories:     Task manager (I’m a strong believer in checklists)    Contact manager    File manager    Time tracker (in fact I like to keep track of a number of metrics for myself)    Text editor/IDEs (Visual Studio, NotePad++, etc.)    Formatted documents (Word), spreadsheets, etc. (basically work documents that need to be “pretty”)    Bug tracker    Build server    Source control    Email    Calendar    Notes    Photo editing/management    RSS feeds    Code documentation    FTP    Database management    Entertainment (music, movies, games, comics)   There is probably more but that’s what I could think of in a couple minutes this morning. So there are items like Zoho that can handle the tasks, contacts, etc. But they’re really all separate apps. My data is in one location, but not what I would consider convenient. On top of that I can’t really tie in any of my code stuff, the entertainment items, etc. Google has a number of these items but at present it’s still 10 separate apps that I have to switch between, so better but not great. I even looked into some web based OSes (eyeOS, etc). Once again, not bad but it’s still mostly a system where I have to switch between 20 or so apps that just run on the OS… So basically I couldn’t find anything really and thus I’ve come to the conclusion that I need to build it.  I’m not sure if I’m going to open source the project completely because I’m not sure how helpful it would be to anyone other than myself. That being said, I figured I would share my progress, give snippets of code, etc. Anything that might be of interest and code that could be useful. But for now I’m in the planning stage, so give me a week and I’ll have more to share. Anyway, happy coding.]]></itunes:summary></item>
<item><title>Craigandrsquo;s Utility Library 3.1 Released</title>
<link>http://www.gutgames.com/post/Craigrsquo3bs-Utility-Library-31-Released.aspx</link>
<author>James Craig</author>
<pubDate>Sun, 25 Mar 2012 14:05:53 GMT</pubDate>
<description><![CDATA[Yesterday I released the latest version of Craig’s Utility Library. This version contains a number of updates and additions including:  Additions     Added DateSpan class     Added GenericDelimited class     Random additions             Added static thread friendly version of Random.Next called ThreadSafeNext.            AOP Manager additions             Added Destroy function to AOPManager (clears out all data so system can be recreated. Really only useful for testing...)            ORM additions             Added PagedCommand and PageCount functions to ObjectBaseClass (same as MicroORM).         In ORM added PagedCommand and PageCount functions (same as MicroORM).         Added Paged/PageCount functions to ObjectBaseClass.         Added PageCount function to ORM Session (forgot about it earlier until, of course, I needed it).         Added Setup function to ORM code to allow defining/setting up mappings (and derived types) at start instead of creating them on the fly.         Added Destroy function to ORM (clears out all data so system can be recreated. Really only useful for testing...)            MicroORM additions             Added ClearAllMappings function to MicroORM (clears out all mappings from the system, so it can be recreated. Really only useful for testing...)            Delimited file additions             Added Parse function, ToDataTable, and ToFile functions to base class            SQLHelper additions             Added ExecuteBulkCopy            Object Extensions             ThrowIfTrue         ThrowIfFalse         TryTo (converts the type, but still returns it as an object. Good for converting string to int, int to float, etc. but still need it as an object for whatever reason)            IEnumerable Extensions             FalseForAll         FalseForAny         TrueForAll         TrueForAny         ThrowIfFalseForAll         ThrowIfFalseForAny         ThrowIfTrueForAll         ThrowIfTrueForAny         ElementsBetween         First         Last         ToDataTable         ToCSV         ToDelimitedFile            string Extensions             ExpandTabs         StripLeft         StripRight         Pluralize         Singularize         Center         MaskLeft         MaskRight         UrlDecode         UrlEncode            FileInfo Extensions             DriveInfo         Execute            DirectoryInfo Extensions             DriveInfo         DeleteDirectoriesNewerThan         DeleteDirectoriesOlderThan            DateTime Extensions             FirstDayOfQuarter         FirstDayOfYear         LastDayOfQuarter         LastDayOfYear         ConvertToTimeZone (assumes that times are in UTC time)         LocalTimeZone         AddWeeks         Age         BeginningOfDay         EndOfDay         IsToday         SetTime         UTCOffset            Uri Extensions             Execute (opens a URL in the default browser)            DataTable Extensions             ToList         ToCSV         ToDelimitedFile            TimeSpan Extensions             Years         Months         DaysRemainder           Fixes/Updates     Modified TrueForAll to accept more than one Predicate.     Changed ThrowIfDefault, ThrowIfNull, ThrowIfNullOrDBNull, and ThrowIfNullOrEmpty to return the original value instead of being void.     Fixed Remove and RemoveRange so that they would work with fixed length collections, arrays, etc. (Note that the collection is no longer directly changed, the returned value is now the collection minus the removed items)     Changed SQLHelper methods that were returning void. They now return the SQLHelper object (basically allowing for a more fluent interface).     Added PageCount and PagedCommand functions for MicroORM. These functions take an SQL command to determine the data to return (you can't have an order by clause, but this allows a lot more freedom when coming up with what to return).     Changed StopWatch class to actually use System.Diagnostics.Stopwatch class for greater precision when timing. (May remove this class in the future)     Switched Save function on ObjectBaseClass to take an IEnumerable instead of a list of objects.     Fixed issues in ORM when an item contains a ManyToMany or ManyToOne mapping that is the same type (for instance class A contains a list of type A).     Fixed issue in ORM where if string mapping is declared MAX by entering -1 (no longer limits the text in that field to 100 characters).     Fixed bug in ORM code so that Readable and Writable fields on the database are respected.    Bitmap extensions are now multithreaded and thus much faster.   And there’s even a bit more in there, but I’m tired of writing at the moment. So go, download the latest version and happy coding… Oh and I just realized that apparently my nightly build broke around the end of February. Apparently the hodgepodge of third party tools that I assembled didn’t work well together… Anyway, I’ll hopefully get that up and running again soon.]]></description>
<itunes:subtitle>Craigandrsquo;s Utility Library 3.1 Released</itunes:subtitle><itunes:summary><![CDATA[Yesterday I released the latest version of Craig’s Utility Library. This version contains a number of updates and additions including:  Additions     Added DateSpan class     Added GenericDelimited class     Random additions             Added static thread friendly version of Random.Next called ThreadSafeNext.            AOP Manager additions             Added Destroy function to AOPManager (clears out all data so system can be recreated. Really only useful for testing...)            ORM additions             Added PagedCommand and PageCount functions to ObjectBaseClass (same as MicroORM).         In ORM added PagedCommand and PageCount functions (same as MicroORM).         Added Paged/PageCount functions to ObjectBaseClass.         Added PageCount function to ORM Session (forgot about it earlier until, of course, I needed it).         Added Setup function to ORM code to allow defining/setting up mappings (and derived types) at start instead of creating them on the fly.         Added Destroy function to ORM (clears out all data so system can be recreated. Really only useful for testing...)            MicroORM additions             Added ClearAllMappings function to MicroORM (clears out all mappings from the system, so it can be recreated. Really only useful for testing...)            Delimited file additions             Added Parse function, ToDataTable, and ToFile functions to base class            SQLHelper additions             Added ExecuteBulkCopy            Object Extensions             ThrowIfTrue         ThrowIfFalse         TryTo (converts the type, but still returns it as an object. Good for converting string to int, int to float, etc. but still need it as an object for whatever reason)            IEnumerable Extensions             FalseForAll         FalseForAny         TrueForAll         TrueForAny         ThrowIfFalseForAll         ThrowIfFalseForAny         ThrowIfTrueForAll         ThrowIfTrueForAny         ElementsBetween         First         Last         ToDataTable         ToCSV         ToDelimitedFile            string Extensions             ExpandTabs         StripLeft         StripRight         Pluralize         Singularize         Center         MaskLeft         MaskRight         UrlDecode         UrlEncode            FileInfo Extensions             DriveInfo         Execute            DirectoryInfo Extensions             DriveInfo         DeleteDirectoriesNewerThan         DeleteDirectoriesOlderThan            DateTime Extensions             FirstDayOfQuarter         FirstDayOfYear         LastDayOfQuarter         LastDayOfYear         ConvertToTimeZone (assumes that times are in UTC time)         LocalTimeZone         AddWeeks         Age         BeginningOfDay         EndOfDay         IsToday         SetTime         UTCOffset            Uri Extensions             Execute (opens a URL in the default browser)            DataTable Extensions             ToList         ToCSV         ToDelimitedFile            TimeSpan Extensions             Years         Months         DaysRemainder           Fixes/Updates     Modified TrueForAll to accept more than one Predicate.     Changed ThrowIfDefault, ThrowIfNull, ThrowIfNullOrDBNull, and ThrowIfNullOrEmpty to return the original value instead of being void.     Fixed Remove and RemoveRange so that they would work with fixed length collections, arrays, etc. (Note that the collection is no longer directly changed, the returned value is now the collection minus the removed items)     Changed SQLHelper methods that were returning void. They now return the SQLHelper object (basically allowing for a more fluent interface).     Added PageCount and PagedCommand functions for MicroORM. These functions take an SQL command to determine the data to return (you can't have an order by clause, but this allows a lot more freedom when coming up with what to return).     Changed StopWatch class to actually use System.Diagnostics.Stopwatch class for greater precision when timing. (May remove this class in the future)     Switched Save function on ObjectBaseClass to take an IEnumerable instead of a list of objects.     Fixed issues in ORM when an item contains a ManyToMany or ManyToOne mapping that is the same type (for instance class A contains a list of type A).     Fixed issue in ORM where if string mapping is declared MAX by entering -1 (no longer limits the text in that field to 100 characters).     Fixed bug in ORM code so that Readable and Writable fields on the database are respected.    Bitmap extensions are now multithreaded and thus much faster.   And there’s even a bit more in there, but I’m tired of writing at the moment. So go, download the latest version and happy coding… Oh and I just realized that apparently my nightly build broke around the end of February. Apparently the hodgepodge of third party tools that I assembled didn’t work well together… Anyway, I’ll hopefully get that up and running again soon.]]></itunes:summary></item>
<item><title>Small Changes, Big Speed Ups</title>
<link>http://www.gutgames.com/post/Small-Changes2c-Big-Speed-Ups.aspx</link>
<author>James Craig</author>
<pubDate>Sun, 04 Mar 2012 13:11:30 GMT</pubDate>
<description><![CDATA[As of late I've been busy working on a new project. A side project that has arisen because I'm annoyed at the other products out there that accomplish the task (very specific industry where they charge 500 times what should be charged, they charge for each component when it should be one product, etc)... I've gone from basic design and storyboards to fleshing out most of the backend. The only thing left is connecting the front end to the API. Anyway, I've got some free time so I figured I'd post a bit about what I've been doing with my utility library and an interesting find.  One of the things that I've been focusing on is speeding up the code in my utility library. There are a number of functions that were a bit slow to say the least. For instance all of the Bitmap extensions originally were unusable on any image over 400 pixels wide, but I then switched to unsafe code which cut the amount of time it took to run each of those functions by about a factor of 10. However I've been running into people who need to use the code on images that are much, much larger than I expected. I'm talking 10240 x 10240 type images, which is insane when you consider a 10 megapixel image is about 3200x3200 (basically we're talking about a 105 megapixel image here). So I looked at my available options and looked for a way to improve the speed a bit more... And I found it in multithreading.  In .Net 4 we were given the Task Parallel Library. Prior to the TPL, in order to do anything in parallel, you had to manage threads yourself, deal with a thread pool, etc. To be honest it was a bit of a pain and was one of the reasons no one really went down that route unless they had to. But with the TPL, you can pretty much just take the following:             1: for(int x=0;xandlt;10;++x)<br /><br /><br />       2: {<br /><br /><br />       3:     DoSomething();<br /><br /><br />       4: }<br /><br /><br /><br />and convert it to being multithreading by just doing the following:<br /><br /><br />  <br />       1: Parallel.For(0,10,x=andgt;{<br /><br /><br />       2:     DoSomething();<br /><br /><br />       3: });<br /><br /><br /><br />Basically we just send it the start and stop values, give it an Action, and we're done as the TPL takes care of the rest. This can be done with most of your for and foreach loops but there are some things to keep in mind. First, it doesn't seem to lock data from outside the Action from what I can tell. So if you try to manipulate the exact same location in an array from two of the threads that it spawns at the same time, you're going to get some bugs. On top of that not everything in the .Net world is thread safe (for instance trying to generate a random number using the Random class is a huge problem). But keeping that sort of stuff in mind, it's still pretty easy to use and works quite well.<br /><br />In the case of my Bitmap extensions, I found that generally speaking I was reading from a number of pixels in one image (that wasn't changing) and modifying one pixel in the destination image (and only setting it once). As such my, for the most part, wasn't going to be effected too much by the potential pitfalls (although the random number generation did pop up). So for instance the Negative function used to be:<br /><br /><br />  <br />       1: public static Bitmap Negative(this Bitmap OriginalImage, string FileName = andquot;andquot;)<br /><br /><br />       2: {<br /><br /><br />       3:     if (OriginalImage == null)<br /><br /><br />       4:         throw new ArgumentNullException(andquot;OriginalImageandquot;);<br /><br /><br />       5:     ImageFormat FormatUsing = FileName.GetImageFormat();<br /><br /><br />       6:     Bitmap NewBitmap = new Bitmap(OriginalImage.Width, OriginalImage.Height);<br /><br /><br />       7:     BitmapData NewData = NewBitmap.LockImage();<br /><br /><br />       8:     BitmapData OldData = OriginalImage.LockImage();<br /><br /><br />       9:     int NewPixelSize = NewData.GetPixelSize();<br /><br /><br />      10:     int OldPixelSize = OldData.GetPixelSize();<br /><br /><br />      11:     for (int x = 0; x andlt; NewBitmap.Width; ++x)<br /><br /><br />      12:     {<br /><br /><br />      13:         for (int y = 0; y andlt; NewBitmap.Height; ++y)<br /><br /><br />      14:         {<br /><br /><br />      15:             Color CurrentPixel = OldData.GetPixel(x, y, OldPixelSize);<br /><br /><br />      16:             Color TempValue = Color.FromArgb(255 - CurrentPixel.R, 255 - CurrentPixel.G, 255 - CurrentPixel.B);<br /><br /><br />      17:             NewData.SetPixel(x, y, TempValue, NewPixelSize);<br /><br /><br />      18:         }<br /><br /><br />      19:     }<br /><br /><br />      20:     NewBitmap.UnlockImage(NewData);<br /><br /><br />      21:     OriginalImage.UnlockImage(OldData);<br /><br /><br />      22:     if (!string.IsNullOrEmpty(FileName))<br /><br /><br />      23:         NewBitmap.Save(FileName, FormatUsing);<br /><br /><br />      24:     return NewBitmap;<br /><br /><br />      25: }<br /><br /><br /><br />But by changing it to this:<br /><br /><br />  <br />       1: public static Bitmap Negative(this Bitmap OriginalImage, string FileName = andquot;andquot;)<br /><br /><br />       2: {<br /><br /><br />       3:     OriginalImage.ThrowIfNull(andquot;OriginalImageandquot;);<br /><br /><br />       4:     ImageFormat FormatUsing = FileName.GetImageFormat();<br /><br /><br />       5:     Bitmap NewBitmap = new Bitmap(OriginalImage.Width, OriginalImage.Height);<br /><br /><br />       6:     BitmapData NewData = NewBitmap.LockImage();<br /><br /><br />       7:     BitmapData OldData = OriginalImage.LockImage();<br /><br /><br />       8:     int NewPixelSize = NewData.GetPixelSize();<br /><br /><br />       9:     int OldPixelSize = OldData.GetPixelSize();<br /><br /><br />      10:     int Width = NewBitmap.Width;<br /><br /><br />      11:     int Height = NewBitmap.Height;<br /><br /><br />      12:     Parallel.For(0, Width, x =andgt;<br /><br /><br />      13:     {<br /><br /><br />      14:         for (int y = 0; y andlt; Height; ++y)<br /><br /><br />      15:         {<br /><br /><br />      16:             Color CurrentPixel = OldData.GetPixel(x, y, OldPixelSize);<br /><br /><br />      17:             Color TempValue = Color.FromArgb(255 - CurrentPixel.R, 255 - CurrentPixel.G, 255 - CurrentPixel.B);<br /><br /><br />      18:             NewData.SetPixel(x, y, TempValue, NewPixelSize);<br /><br /><br />      19:         }<br /><br /><br />      20:     });<br /><br /><br />      21:     NewBitmap.UnlockImage(NewData);<br /><br /><br />      22:     OriginalImage.UnlockImage(OldData);<br /><br /><br />      23:     if (!string.IsNullOrEmpty(FileName))<br /><br /><br />      24:         NewBitmap.Save(FileName, FormatUsing);<br /><br /><br />      25:     return NewBitmap;<br /><br /><br />      26: }<br /><br /><br /><br />I get the image being worked on by multiple processors, speeding up the code by about 400% (the original took about 40ms to run on my test image and about 10ms after the change, but it would depend on how many cores you have on your system, etc. as to how much of a speed up you'll see). But all I really had to do was change the outer loop and I got an instant speed boost. The next item I was going to look at was my ORM and MicroORM and this is where I ran into my little surprise...<br /><br />So one of the things that I do in these cases is I set up a small app to run a number of times (usually something like 10000 times) to get my base, I go and make my modifications and go back and test to see if it made an improvement to the run time. I use my Profiler code for this. In this instance I was just curious how the SQLHelper, ORM, and MicroORM code stacked up because each one is built on top of the other (SQLHelper-andgt;MicroORM-andgt;ORM). And here is where I was surprised. I did a couple tests, inserting a single entry, updating it, selecting one entry, selecting all entries from a table, etc. I was expecting the SQLHelper to be the fastest, the MicroORM next, and ORM the slowest. And I was correct in that assessment, however it wasn't the large spread that I was expecting. For the average insert the times were 4.92ms, 4.97ms, and 5.09ms (I have an SSD, database was local, my processor is pretty freakin good, etc. plus the data was small, only a couple of strings, float, decimal, int, DateTime, long, and bool. I didn't send it anything complex), That's a .17ms difference. The select, 4.53ms, 4.60ms, 4.69ms. That's .16ms... They're all like that. As far as I can tell I've inadvertantly built an ORM that does lazy loading, deals with multiple databases, etc. that's about as fast as straight SQL. Well, almost anyway. Because there are a number of tricks you can do to speed up things when you're dealing with straight SQL.<br /><br />For instance inserting those 10,000 rows took a total of 49 seconds when doing each one individually. However we can simply use the SQLBulkCopy class and have that insert the 10,000 rows in a total of 525ms... By the way, the SQLBulkCopy class is now being used by SQLHelper (the ExecuteBulkCopy function). We can also update multiple rows at once when using SQLHelper (which the ORM and MicroORM doesn't quite do yet). But there are things that I could do at the MicroORM and ORM levels to give them an advantage (caching being a big one, which I don't do yet). There are a couple of other things also, but other than that it's not a bad surprise. Anyway, take a look, leave feedback, and happy coding.]]></description>
<itunes:subtitle>Small Changes, Big Speed Ups</itunes:subtitle><itunes:summary><![CDATA[As of late I've been busy working on a new project. A side project that has arisen because I'm annoyed at the other products out there that accomplish the task (very specific industry where they charge 500 times what should be charged, they charge for each component when it should be one product, etc)... I've gone from basic design and storyboards to fleshing out most of the backend. The only thing left is connecting the front end to the API. Anyway, I've got some free time so I figured I'd post a bit about what I've been doing with my utility library and an interesting find.  One of the things that I've been focusing on is speeding up the code in my utility library. There are a number of functions that were a bit slow to say the least. For instance all of the Bitmap extensions originally were unusable on any image over 400 pixels wide, but I then switched to unsafe code which cut the amount of time it took to run each of those functions by about a factor of 10. However I've been running into people who need to use the code on images that are much, much larger than I expected. I'm talking 10240 x 10240 type images, which is insane when you consider a 10 megapixel image is about 3200x3200 (basically we're talking about a 105 megapixel image here). So I looked at my available options and looked for a way to improve the speed a bit more... And I found it in multithreading.  In .Net 4 we were given the Task Parallel Library. Prior to the TPL, in order to do anything in parallel, you had to manage threads yourself, deal with a thread pool, etc. To be honest it was a bit of a pain and was one of the reasons no one really went down that route unless they had to. But with the TPL, you can pretty much just take the following:             1: for(int x=0;xandlt;10;++x)<br /><br /><br />       2: {<br /><br /><br />       3:     DoSomething();<br /><br /><br />       4: }<br /><br /><br /><br />and convert it to being multithreading by just doing the following:<br /><br /><br />  <br />       1: Parallel.For(0,10,x=andgt;{<br /><br /><br />       2:     DoSomething();<br /><br /><br />       3: });<br /><br /><br /><br />Basically we just send it the start and stop values, give it an Action, and we're done as the TPL takes care of the rest. This can be done with most of your for and foreach loops but there are some things to keep in mind. First, it doesn't seem to lock data from outside the Action from what I can tell. So if you try to manipulate the exact same location in an array from two of the threads that it spawns at the same time, you're going to get some bugs. On top of that not everything in the .Net world is thread safe (for instance trying to generate a random number using the Random class is a huge problem). But keeping that sort of stuff in mind, it's still pretty easy to use and works quite well.<br /><br />In the case of my Bitmap extensions, I found that generally speaking I was reading from a number of pixels in one image (that wasn't changing) and modifying one pixel in the destination image (and only setting it once). As such my, for the most part, wasn't going to be effected too much by the potential pitfalls (although the random number generation did pop up). So for instance the Negative function used to be:<br /><br /><br />  <br />       1: public static Bitmap Negative(this Bitmap OriginalImage, string FileName = andquot;andquot;)<br /><br /><br />       2: {<br /><br /><br />       3:     if (OriginalImage == null)<br /><br /><br />       4:         throw new ArgumentNullException(andquot;OriginalImageandquot;);<br /><br /><br />       5:     ImageFormat FormatUsing = FileName.GetImageFormat();<br /><br /><br />       6:     Bitmap NewBitmap = new Bitmap(OriginalImage.Width, OriginalImage.Height);<br /><br /><br />       7:     BitmapData NewData = NewBitmap.LockImage();<br /><br /><br />       8:     BitmapData OldData = OriginalImage.LockImage();<br /><br /><br />       9:     int NewPixelSize = NewData.GetPixelSize();<br /><br /><br />      10:     int OldPixelSize = OldData.GetPixelSize();<br /><br /><br />      11:     for (int x = 0; x andlt; NewBitmap.Width; ++x)<br /><br /><br />      12:     {<br /><br /><br />      13:         for (int y = 0; y andlt; NewBitmap.Height; ++y)<br /><br /><br />      14:         {<br /><br /><br />      15:             Color CurrentPixel = OldData.GetPixel(x, y, OldPixelSize);<br /><br /><br />      16:             Color TempValue = Color.FromArgb(255 - CurrentPixel.R, 255 - CurrentPixel.G, 255 - CurrentPixel.B);<br /><br /><br />      17:             NewData.SetPixel(x, y, TempValue, NewPixelSize);<br /><br /><br />      18:         }<br /><br /><br />      19:     }<br /><br /><br />      20:     NewBitmap.UnlockImage(NewData);<br /><br /><br />      21:     OriginalImage.UnlockImage(OldData);<br /><br /><br />      22:     if (!string.IsNullOrEmpty(FileName))<br /><br /><br />      23:         NewBitmap.Save(FileName, FormatUsing);<br /><br /><br />      24:     return NewBitmap;<br /><br /><br />      25: }<br /><br /><br /><br />But by changing it to this:<br /><br /><br />  <br />       1: public static Bitmap Negative(this Bitmap OriginalImage, string FileName = andquot;andquot;)<br /><br /><br />       2: {<br /><br /><br />       3:     OriginalImage.ThrowIfNull(andquot;OriginalImageandquot;);<br /><br /><br />       4:     ImageFormat FormatUsing = FileName.GetImageFormat();<br /><br /><br />       5:     Bitmap NewBitmap = new Bitmap(OriginalImage.Width, OriginalImage.Height);<br /><br /><br />       6:     BitmapData NewData = NewBitmap.LockImage();<br /><br /><br />       7:     BitmapData OldData = OriginalImage.LockImage();<br /><br /><br />       8:     int NewPixelSize = NewData.GetPixelSize();<br /><br /><br />       9:     int OldPixelSize = OldData.GetPixelSize();<br /><br /><br />      10:     int Width = NewBitmap.Width;<br /><br /><br />      11:     int Height = NewBitmap.Height;<br /><br /><br />      12:     Parallel.For(0, Width, x =andgt;<br /><br /><br />      13:     {<br /><br /><br />      14:         for (int y = 0; y andlt; Height; ++y)<br /><br /><br />      15:         {<br /><br /><br />      16:             Color CurrentPixel = OldData.GetPixel(x, y, OldPixelSize);<br /><br /><br />      17:             Color TempValue = Color.FromArgb(255 - CurrentPixel.R, 255 - CurrentPixel.G, 255 - CurrentPixel.B);<br /><br /><br />      18:             NewData.SetPixel(x, y, TempValue, NewPixelSize);<br /><br /><br />      19:         }<br /><br /><br />      20:     });<br /><br /><br />      21:     NewBitmap.UnlockImage(NewData);<br /><br /><br />      22:     OriginalImage.UnlockImage(OldData);<br /><br /><br />      23:     if (!string.IsNullOrEmpty(FileName))<br /><br /><br />      24:         NewBitmap.Save(FileName, FormatUsing);<br /><br /><br />      25:     return NewBitmap;<br /><br /><br />      26: }<br /><br /><br /><br />I get the image being worked on by multiple processors, speeding up the code by about 400% (the original took about 40ms to run on my test image and about 10ms after the change, but it would depend on how many cores you have on your system, etc. as to how much of a speed up you'll see). But all I really had to do was change the outer loop and I got an instant speed boost. The next item I was going to look at was my ORM and MicroORM and this is where I ran into my little surprise...<br /><br />So one of the things that I do in these cases is I set up a small app to run a number of times (usually something like 10000 times) to get my base, I go and make my modifications and go back and test to see if it made an improvement to the run time. I use my Profiler code for this. In this instance I was just curious how the SQLHelper, ORM, and MicroORM code stacked up because each one is built on top of the other (SQLHelper-andgt;MicroORM-andgt;ORM). And here is where I was surprised. I did a couple tests, inserting a single entry, updating it, selecting one entry, selecting all entries from a table, etc. I was expecting the SQLHelper to be the fastest, the MicroORM next, and ORM the slowest. And I was correct in that assessment, however it wasn't the large spread that I was expecting. For the average insert the times were 4.92ms, 4.97ms, and 5.09ms (I have an SSD, database was local, my processor is pretty freakin good, etc. plus the data was small, only a couple of strings, float, decimal, int, DateTime, long, and bool. I didn't send it anything complex), That's a .17ms difference. The select, 4.53ms, 4.60ms, 4.69ms. That's .16ms... They're all like that. As far as I can tell I've inadvertantly built an ORM that does lazy loading, deals with multiple databases, etc. that's about as fast as straight SQL. Well, almost anyway. Because there are a number of tricks you can do to speed up things when you're dealing with straight SQL.<br /><br />For instance inserting those 10,000 rows took a total of 49 seconds when doing each one individually. However we can simply use the SQLBulkCopy class and have that insert the 10,000 rows in a total of 525ms... By the way, the SQLBulkCopy class is now being used by SQLHelper (the ExecuteBulkCopy function). We can also update multiple rows at once when using SQLHelper (which the ORM and MicroORM doesn't quite do yet). But there are things that I could do at the MicroORM and ORM levels to give them an advantage (caching being a big one, which I don't do yet). There are a couple of other things also, but other than that it's not a bad surprise. Anyway, take a look, leave feedback, and happy coding.]]></itunes:summary></item>
<item><title>Craigandrsquo;s Utility Library 3.0 Released</title>
<link>http://www.gutgames.com/post/Craigrsquo3bs-Utility-Library-30-Released.aspx</link>
<author>James Craig</author>
<pubDate>Tue, 20 Dec 2011 21:37:44 GMT</pubDate>
<description><![CDATA[OK, so I should have uploaded this last week but I’ve been a bit lazy (I’m on vacation). That being said, the big news is that Craig’s Utility Library has a new version. However, it’s not 2.3 (which would be the next version sequentially) but 3.0. The reason for the jump is that this version is not exactly compatible with the older version. Much of the code has been reworked completely (much of the static methods are now extension methods, etc). Here is just the short list that they would let me put up on CodePlex:  Fixes     Added fix for length of columns when dealing with nvarchars in SQLServer class.    Added fix for Map objects that were set to cascade where ManyToMany and ManyToOne objects underneath were not cascading properly.    Added Any and All functions to ObjectBaseClass that accept SQL Commands/CommandTypes.    Fixed cascading saves for Mapped objects in ORM.    Added check in StringID and StringReference for -1 (max length), so that the validation actually works on update...    Added fix for ZipFile when calling AddFile (now creates the zip file correctly).    Added check to ORM code to make sure that load commands aren't overwritten with defaults.    Fixed issue with ObjectBaseClass if the instance returned by Any is null.    Fixed bug in DataMapper when using the AutoMap feature.    Fixed small bug in RGBHistogram's Equalize function as well as Equalize function in BitmapExtensions.    Fixed issue that allows unsafe code to be tested/run (seems to be related to updating to 4.0).    Fixed bug in Random class's NextColor function.    Fixed issue with ArgsParser code involving double quotes and reduced code a bit.    Fixed minor issues with RSAEncryption class.    Fixed minor issues/made code simpler for Conversion, Matrix, Set, and Vector3 classes.    Fixed a couple of bugs in vector class (initial size of items not set right, removing first item in list, etc.)    Fixed various issues/improved BinaryTree class   Changes  Most static functions have been moved to various extension methods and a number of functions have been added (too many to list here).   On top of that a number of changes have been made to various classes:     Added ability in ProfilerManager to get data for a specific function and made ProfilerInfo public    Changed the parameters of the Column DataClass (now has a generic default value, uses DbType instead of SqlDbType for the DataType property, etc)    Added ability to query list of users who logged into a machine (WMI code)    Added a ClearMappings function to MicroORM.    Updated SQLHelper's code (removed functions that are no longer used, instead keeping generic versions).    Merged AddParameter and AddOutputParameter into one function (and GetParameter and GetOutputParameter) and changed order of a couple parameters.    Updated ErrorManager code to use extension methods moved from the Web namespace (DumpCache, DumpApplicationState, etc).    Updated WebPageThumbnail code to use some default values to make things simpler.    Made TypeMapping class a bit more fluent to make adding mappings easier.    Simplified Validator code and added a number of functions for new validation rules.    Finished adding IoC code (very simple IoC container).    Rewrote LDAP code (simplified).    Reworked some of the Reflection.Emit classes (mostly to reduce redundant functions, replace wordy code, etc.)    Added GenericStringFormatter class (used by FormatString function in the StringExtensions class)    Moved NaiveBayes class to AI namespace.    Improved ListMapping functionality    Added functions to priority queue for adding items, improved Pop functionality.    Added DateSpan class.    Moved Cisco classes to FileFormats namespace   Also Items Have been removed due to the fact that they were either too difficult to maintain or simply not being used:     Removed Youtube code (will eventually replace this with Google API namespace.    Removed FOAF and APML helpers as neither format seem to be used...    Removed Speech namespace (wasn't really maintaining it)...    Removed Pair and Triple classes (not needed with addition of System.Tuple)   This doesn’t include the new list of extension methods:  Utilities.DataTypes.ExtensionMethods     Array extensions             Clear         Combine            DateTime extensions             DaysInMonth         DaysLeftInMonth         DaysLeftInYear         FirstDayOfMonth         FirstDayOfWeek         FromUnixTime (actually extension for int and long values)         IsInFuture         IsInPast         IsWeekDay         IsWeekEnd         LastDayOfMonth         LastDayOfWeek         ToUnix            Generic object extensions             If         NotIf         Return         Chain         Do         Execute            ICollection extensions             AddAndReturn         AddRange         AddIf         AddIfUnique         Remove         RemoveRange            IComparable extensions             Between            IDictionary extensions             Sort         SortByValue            IEnumerable extensions             Exists         For         ForEach         ForParallel         ForEachParallel         IsNullOrEmpty         RemoveDefaults         ToArray         ToString         TrueForAll         TryAll         TryAllParallel            MatchCollection extensions             Where            string extensions             Encode         FromBase64         Left         Right         ToBase64         ToByteArray         ToFirstCharacterUpperCase         ToSentenceCapitalize         ToTitleCase         NumberTimesOccurs         Reverse         FilterOutText         KeepFilterText         AlphaNumericOnly         AlphaCharactersOnly         NumericOnly         IsUnicode         FormatString         RegexFormat            Various type conversion/type checking extensions             FormatToString         IsNotDefault         IsDefault         IsNotNull         IsNull         IsNotNullOrDBNull         IsNullOrDBNull         NullCheck         ThrowIfDefault         ThrowIfNullOrEmpty         ThrowIfNullOrDBNull         ToSQLDbType         ToDbType         ToType         TryTo            Various value type extensions             ToBool (int)         ToInt (bool)         ToBase64String (byte array)         ToEncodedString (byte array)         IsUnicode (byte array)          Utilities.IO.ExtensionMethods     Serialization extensions             ToBinary         ToJSON         ToSOAP         ToXML         ToObject         JSONToObject         SOAPToObject         XMLToObject            Uri extensions             Read         ReadBinary            Math extensions             Betweek         Clamp         Factorial         Max         Median         Min         Mode         Pow         Round         StandardDeviation         Sqrt         Variance         Permute          Utilities.SQL.ExtensionMethods     DbCommand extensions             AddParameter         BeginTransaction         ClearParameters         Close         Commit         ExecuteDataSet         ExecuteScalar         GetOutputParameter         Open         Rollback            DbDataReader extensions             GetParameter          Utilities.Compression.ExtensionMethods     Compress (both byte arrays and strings)     Decompress (both byte arrays and strings)  Utilities.Encryption.ExtensionMethods     Hash (Now handles all hash algorithms in one function for both byte arrays and strings)     Encrypt (Handles any symmetric encryption algorithm inside .Net)     Decrypt (Handles any symmetric encryption algorithm inside .Net)  Utilities.IO.ExtensionMethods     DirectoryInfo extensions             CopyTo         DeleteAll         DeleteFiles         DeleteFilesNewerThan         DeleteFilesOlderThan         Size         SetAttribute            FileInfo extensions             Append         CompareTo         Read         ReadBinary         Save         SaveAsync         SetAttributes            String extensions             RemoveIllegalDirectoryNameCharacters         RemoveIllegalFileNameCharacters          Utilities.Web.ExtensionMethods     Web related extensions             AbsoluteRoot         AddScriptFile         ContainsHTML         HTTPCompress         IsEncodingAccepted         RelativeRoot         RemoveURLIllegalCharacters         SetEncoding         StripHTML            IPAddress extensions             GetHostName            Minification             Combine (can be used for HTML,JavaScript, or CSS)         Minify (can be used for HTML, JavaScript, or CSS)            HttpRequest extensions             IsMobile          Utilities.Image.ExtensionMethods     All Bitmap functions were moved             Added ToBase64 extension method         Added DrawRoundedRectangle extension            Screen extensions             TakeScreenShot          Utilities.Error.ExtensionMethods     Various error related extensions             DumpApplicationState         DumpCache         DumpCookies         DumpRequestVariable         DumpResponseVariable         DumpServerVars         DumpSession          Utilities.Reflection.ExtensionMethods     Various reflection related extensions             CallMethod         CreateInstance         DumpProperties         GetAttribute         GetAttributes         GetName         GetObjects         GetProperty         GetPropertyGetter         GetPropertyName         GetPropertyType         GetPropertySetter         GetTypes         IsIEnumerable         IsOfType         Load         LoadAssemblies         MarkedWith         MakeShallowCopy         SetProperty         ToLongVersionString         ToShortVersionString          Utilities.Environment.ExtensionMethods     Process related extensions             KillProcessAsync         GetInformation           I know that’s a long list, but this isn’t everything that has been updated. On top of all of that, there is now a set of tests that is available with the code. And I’m working on getting a nightly build going. With the nightly build, I’m going to automatically publish to NuGet. So if you’re using NuGet to get it, you’re going to be getting the nightly build. Anyway, that’s it for this post. So download the code, leave comments, and happy coding.]]></description>
<itunes:subtitle>Craigandrsquo;s Utility Library 3.0 Released</itunes:subtitle><itunes:summary><![CDATA[OK, so I should have uploaded this last week but I’ve been a bit lazy (I’m on vacation). That being said, the big news is that Craig’s Utility Library has a new version. However, it’s not 2.3 (which would be the next version sequentially) but 3.0. The reason for the jump is that this version is not exactly compatible with the older version. Much of the code has been reworked completely (much of the static methods are now extension methods, etc). Here is just the short list that they would let me put up on CodePlex:  Fixes     Added fix for length of columns when dealing with nvarchars in SQLServer class.    Added fix for Map objects that were set to cascade where ManyToMany and ManyToOne objects underneath were not cascading properly.    Added Any and All functions to ObjectBaseClass that accept SQL Commands/CommandTypes.    Fixed cascading saves for Mapped objects in ORM.    Added check in StringID and StringReference for -1 (max length), so that the validation actually works on update...    Added fix for ZipFile when calling AddFile (now creates the zip file correctly).    Added check to ORM code to make sure that load commands aren't overwritten with defaults.    Fixed issue with ObjectBaseClass if the instance returned by Any is null.    Fixed bug in DataMapper when using the AutoMap feature.    Fixed small bug in RGBHistogram's Equalize function as well as Equalize function in BitmapExtensions.    Fixed issue that allows unsafe code to be tested/run (seems to be related to updating to 4.0).    Fixed bug in Random class's NextColor function.    Fixed issue with ArgsParser code involving double quotes and reduced code a bit.    Fixed minor issues with RSAEncryption class.    Fixed minor issues/made code simpler for Conversion, Matrix, Set, and Vector3 classes.    Fixed a couple of bugs in vector class (initial size of items not set right, removing first item in list, etc.)    Fixed various issues/improved BinaryTree class   Changes  Most static functions have been moved to various extension methods and a number of functions have been added (too many to list here).   On top of that a number of changes have been made to various classes:     Added ability in ProfilerManager to get data for a specific function and made ProfilerInfo public    Changed the parameters of the Column DataClass (now has a generic default value, uses DbType instead of SqlDbType for the DataType property, etc)    Added ability to query list of users who logged into a machine (WMI code)    Added a ClearMappings function to MicroORM.    Updated SQLHelper's code (removed functions that are no longer used, instead keeping generic versions).    Merged AddParameter and AddOutputParameter into one function (and GetParameter and GetOutputParameter) and changed order of a couple parameters.    Updated ErrorManager code to use extension methods moved from the Web namespace (DumpCache, DumpApplicationState, etc).    Updated WebPageThumbnail code to use some default values to make things simpler.    Made TypeMapping class a bit more fluent to make adding mappings easier.    Simplified Validator code and added a number of functions for new validation rules.    Finished adding IoC code (very simple IoC container).    Rewrote LDAP code (simplified).    Reworked some of the Reflection.Emit classes (mostly to reduce redundant functions, replace wordy code, etc.)    Added GenericStringFormatter class (used by FormatString function in the StringExtensions class)    Moved NaiveBayes class to AI namespace.    Improved ListMapping functionality    Added functions to priority queue for adding items, improved Pop functionality.    Added DateSpan class.    Moved Cisco classes to FileFormats namespace   Also Items Have been removed due to the fact that they were either too difficult to maintain or simply not being used:     Removed Youtube code (will eventually replace this with Google API namespace.    Removed FOAF and APML helpers as neither format seem to be used...    Removed Speech namespace (wasn't really maintaining it)...    Removed Pair and Triple classes (not needed with addition of System.Tuple)   This doesn’t include the new list of extension methods:  Utilities.DataTypes.ExtensionMethods     Array extensions             Clear         Combine            DateTime extensions             DaysInMonth         DaysLeftInMonth         DaysLeftInYear         FirstDayOfMonth         FirstDayOfWeek         FromUnixTime (actually extension for int and long values)         IsInFuture         IsInPast         IsWeekDay         IsWeekEnd         LastDayOfMonth         LastDayOfWeek         ToUnix            Generic object extensions             If         NotIf         Return         Chain         Do         Execute            ICollection extensions             AddAndReturn         AddRange         AddIf         AddIfUnique         Remove         RemoveRange            IComparable extensions             Between            IDictionary extensions             Sort         SortByValue            IEnumerable extensions             Exists         For         ForEach         ForParallel         ForEachParallel         IsNullOrEmpty         RemoveDefaults         ToArray         ToString         TrueForAll         TryAll         TryAllParallel            MatchCollection extensions             Where            string extensions             Encode         FromBase64         Left         Right         ToBase64         ToByteArray         ToFirstCharacterUpperCase         ToSentenceCapitalize         ToTitleCase         NumberTimesOccurs         Reverse         FilterOutText         KeepFilterText         AlphaNumericOnly         AlphaCharactersOnly         NumericOnly         IsUnicode         FormatString         RegexFormat            Various type conversion/type checking extensions             FormatToString         IsNotDefault         IsDefault         IsNotNull         IsNull         IsNotNullOrDBNull         IsNullOrDBNull         NullCheck         ThrowIfDefault         ThrowIfNullOrEmpty         ThrowIfNullOrDBNull         ToSQLDbType         ToDbType         ToType         TryTo            Various value type extensions             ToBool (int)         ToInt (bool)         ToBase64String (byte array)         ToEncodedString (byte array)         IsUnicode (byte array)          Utilities.IO.ExtensionMethods     Serialization extensions             ToBinary         ToJSON         ToSOAP         ToXML         ToObject         JSONToObject         SOAPToObject         XMLToObject            Uri extensions             Read         ReadBinary            Math extensions             Betweek         Clamp         Factorial         Max         Median         Min         Mode         Pow         Round         StandardDeviation         Sqrt         Variance         Permute          Utilities.SQL.ExtensionMethods     DbCommand extensions             AddParameter         BeginTransaction         ClearParameters         Close         Commit         ExecuteDataSet         ExecuteScalar         GetOutputParameter         Open         Rollback            DbDataReader extensions             GetParameter          Utilities.Compression.ExtensionMethods     Compress (both byte arrays and strings)     Decompress (both byte arrays and strings)  Utilities.Encryption.ExtensionMethods     Hash (Now handles all hash algorithms in one function for both byte arrays and strings)     Encrypt (Handles any symmetric encryption algorithm inside .Net)     Decrypt (Handles any symmetric encryption algorithm inside .Net)  Utilities.IO.ExtensionMethods     DirectoryInfo extensions             CopyTo         DeleteAll         DeleteFiles         DeleteFilesNewerThan         DeleteFilesOlderThan         Size         SetAttribute            FileInfo extensions             Append         CompareTo         Read         ReadBinary         Save         SaveAsync         SetAttributes            String extensions             RemoveIllegalDirectoryNameCharacters         RemoveIllegalFileNameCharacters          Utilities.Web.ExtensionMethods     Web related extensions             AbsoluteRoot         AddScriptFile         ContainsHTML         HTTPCompress         IsEncodingAccepted         RelativeRoot         RemoveURLIllegalCharacters         SetEncoding         StripHTML            IPAddress extensions             GetHostName            Minification             Combine (can be used for HTML,JavaScript, or CSS)         Minify (can be used for HTML, JavaScript, or CSS)            HttpRequest extensions             IsMobile          Utilities.Image.ExtensionMethods     All Bitmap functions were moved             Added ToBase64 extension method         Added DrawRoundedRectangle extension            Screen extensions             TakeScreenShot          Utilities.Error.ExtensionMethods     Various error related extensions             DumpApplicationState         DumpCache         DumpCookies         DumpRequestVariable         DumpResponseVariable         DumpServerVars         DumpSession          Utilities.Reflection.ExtensionMethods     Various reflection related extensions             CallMethod         CreateInstance         DumpProperties         GetAttribute         GetAttributes         GetName         GetObjects         GetProperty         GetPropertyGetter         GetPropertyName         GetPropertyType         GetPropertySetter         GetTypes         IsIEnumerable         IsOfType         Load         LoadAssemblies         MarkedWith         MakeShallowCopy         SetProperty         ToLongVersionString         ToShortVersionString          Utilities.Environment.ExtensionMethods     Process related extensions             KillProcessAsync         GetInformation           I know that’s a long list, but this isn’t everything that has been updated. On top of all of that, there is now a set of tests that is available with the code. And I’m working on getting a nightly build going. With the nightly build, I’m going to automatically publish to NuGet. So if you’re using NuGet to get it, you’re going to be getting the nightly build. Anyway, that’s it for this post. So download the code, leave comments, and happy coding.]]></itunes:summary></item>
<item><title>Building an DI Container</title>
<link>http://www.gutgames.com/post/Building-an-DI-Container.aspx</link>
<author>James Craig</author>
<pubDate>Sun, 13 Nov 2011 16:51:57 GMT</pubDate>
<description><![CDATA[It has been a while since I’ve written anything. To say the least things are hectic. Most of which, I can’t really talk about at this point (let’s just say that I’m working on a product for a sector of the business world. I think I can say that much, but not much more until it gets closer to release). Anyway, today I’m finally getting around to talking about one more item that I’ve added to my utility library. Specifically I’ve added a basic DI container (dependency injection).  Note that this next section is an over simplification and I’m tired so if it’s wrong, feel free to say so. Anyway, Dependency injection is a specific form of inversion of control. Inversion of control is when you invert the flow of a system. Instead of one central bit of code deciding how everything is run, it’s up to the individual pieces to know how to do the actual work. For instance, if I call an object factory to create a database connection for me, I don’t care how it’s created or how the connection is doing anything as long as it gets done. And dependency injection is just a specific form of IoC. Instead of hard coding our dependencies in each individual class, we allow someone to pass in the component that they want to use. You can actually do this manually (using a factory pattern, etc.) and still have a form of dependency injection. However you can also automate this process using one of the many dependency injectors out there (I personally like Ninject and based the code below on it). But where’s the fun in using someone else’s when all we have to do is spend an afternoon and build our own.             1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Providers;<br /><br /><br />      28: using Utilities.IoC.Mappings;<br /><br /><br />      29: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      30: using System.Reflection;<br /><br /><br />      31: using System.IO;<br /><br /><br />      32: using Utilities.IO.ExtensionMethods;<br /><br /><br />      33: using Utilities.Reflection.ExtensionMethods;<br /><br /><br />      34: using Utilities.DataTypes.ExtensionMethods;<br /><br /><br />      35: #endregion<br /><br /><br />      36: <br /><br /><br />      37: namespace Utilities.IoC<br /><br /><br />      38: {<br /><br /><br />      39:     /// andlt;summaryandgt;<br /><br /><br />      40:     /// Manager class<br /><br /><br />      41:     /// andlt;/summaryandgt;<br /><br /><br />      42:     public class Manager<br /><br /><br />      43:     {<br /><br /><br />      44:         #region Constructor<br /><br /><br />      45: <br /><br /><br />      46:         /// andlt;summaryandgt;<br /><br /><br />      47:         /// Constructor<br /><br /><br />      48:         /// andlt;/summaryandgt;<br /><br /><br />      49:         public Manager()<br /><br /><br />      50:         {<br /><br /><br />      51:             if (ProviderManager.IsNull())<br /><br /><br />      52:                 ProviderManager = new ProviderManager();<br /><br /><br />      53:             if (MappingManager.IsNull())<br /><br /><br />      54:                 MappingManager = new MappingManager(ProviderManager);<br /><br /><br />      55:         }<br /><br /><br />      56: <br /><br /><br />      57:         #endregion<br /><br /><br />      58: <br /><br /><br />      59:         #region Functions<br /><br /><br />      60: <br /><br /><br />      61:         /// andlt;summaryandgt;<br /><br /><br />      62:         /// Loads all mapping modules found within the assembly<br /><br /><br />      63:         /// andlt;/summaryandgt;<br /><br /><br />      64:         /// andlt;param name=andquot;ModuleAssemblyandquot;andgt;Module assemblyandlt;/paramandgt;<br /><br /><br />      65:         public void Setup(Assembly ModuleAssembly)<br /><br /><br />      66:         {<br /><br /><br />      67:             ProviderManager.Setup(ModuleAssembly);<br /><br /><br />      68:             MappingManager.Setup(ModuleAssembly);<br /><br /><br />      69:         }<br /><br /><br />      70: <br /><br /><br />      71:         /// andlt;summaryandgt;<br /><br /><br />      72:         /// Loads all mapping modules found within the assemblies<br /><br /><br />      73:         /// andlt;/summaryandgt;<br /><br /><br />      74:         /// andlt;param name=andquot;ModuleAssembliesandquot;andgt;Module assembliesandlt;/paramandgt;<br /><br /><br />      75:         public void Setup(IEnumerableandlt;Assemblyandgt; ModuleAssemblies)<br /><br /><br />      76:         {<br /><br /><br />      77:             ModuleAssemblies.ForEach(x =andgt; Setup(x));<br /><br /><br />      78:         }<br /><br /><br />      79: <br /><br /><br />      80:         /// andlt;summaryandgt;<br /><br /><br />      81:         /// Loads all mapping modules found within a specific directory<br /><br /><br />      82:         /// andlt;/summaryandgt;<br /><br /><br />      83:         /// andlt;param name=andquot;Directoryandquot;andgt;Directory to scan for modulesandlt;/paramandgt;<br /><br /><br />      84:         /// andlt;param name=andquot;RecursiveScanandquot;andgt;Determines if sub directories should be scannedandlt;/paramandgt;<br /><br /><br />      85:         public void Setup(string Directory, bool ScanSubDirectories = true)<br /><br /><br />      86:         {<br /><br /><br />      87:             Setup(new DirectoryInfo(Directory).LoadAssemblies(ScanSubDirectories));<br /><br /><br />      88:         }<br /><br /><br />      89: <br /><br /><br />      90:         /// andlt;summaryandgt;<br /><br /><br />      91:         /// Creates an object of the specified type<br /><br /><br />      92:         /// andlt;/summaryandgt;<br /><br /><br />      93:         /// andlt;typeparam name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/typeparamandgt;<br /><br /><br />      94:         /// andlt;returnsandgt;An object of the specified typeandlt;/returnsandgt;<br /><br /><br />      95:         public ServiceType Getandlt;ServiceTypeandgt;()<br /><br /><br />      96:         {<br /><br /><br />      97:             return (ServiceType)Get(typeof(ServiceType));<br /><br /><br />      98:         }<br /><br /><br />      99: <br /><br /><br />     100:         /// andlt;summaryandgt;<br /><br /><br />     101:         /// Creates an object of the specified type associated with the attribute type<br /><br /><br />     102:         /// andlt;/summaryandgt;<br /><br /><br />     103:         /// andlt;typeparam name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/typeparamandgt;<br /><br /><br />     104:         /// andlt;typeparam name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/typeparamandgt;<br /><br /><br />     105:         /// andlt;returnsandgt;An object of the specified typeandlt;/returnsandgt;<br /><br /><br />     106:         public ServiceType Getandlt;ServiceType, AttributeTypeandgt;()<br /><br /><br />     107:         {<br /><br /><br />     108:             return (ServiceType)Get(typeof(ServiceType), typeof(AttributeType));<br /><br /><br />     109:         }<br /><br /><br />     110: <br /><br /><br />     111:         /// andlt;summaryandgt;<br /><br /><br />     112:         /// Creates an object of the specified type<br /><br /><br />     113:         /// andlt;/summaryandgt;<br /><br /><br />     114:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />     115:         /// andlt;returnsandgt;An object of the specified typeandlt;/returnsandgt;<br /><br /><br />     116:         public object Get(Type ServiceType)<br /><br /><br />     117:         {<br /><br /><br />     118:             IMapping Mapping = MappingManager.GetMapping(ServiceType);<br /><br /><br />     119:             if (Mapping.IsNull())<br /><br /><br />     120:                 throw new ArgumentException(andquot;ServiceType not found in mappingsandquot;);<br /><br /><br />     121:             return Mapping.Implementation.Create();<br /><br /><br />     122:         }<br /><br /><br />     123: <br /><br /><br />     124:         /// andlt;summaryandgt;<br /><br /><br />     125:         /// Creates an object of the specified type associated with the attribute type<br /><br /><br />     126:         /// andlt;/summaryandgt;<br /><br /><br />     127:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />     128:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />     129:         /// andlt;returnsandgt;An object of the specified typeandlt;/returnsandgt;<br /><br /><br />     130:         public object Get(Type ServiceType, Type AttributeType)<br /><br /><br />     131:         {<br /><br /><br />     132:             IMapping Mapping = MappingManager.GetMapping(ServiceType, AttributeType);<br /><br /><br />     133:             if (Mapping.IsNull())<br /><br /><br />     134:                 throw new ArgumentException(andquot;ServiceType not found in mappingsandquot;);<br /><br /><br />     135:             return Mapping.Implementation.Create();<br /><br /><br />     136:         }<br /><br /><br />     137: <br /><br /><br />     138:         #endregion<br /><br /><br />     139: <br /><br /><br />     140:         #region Properties<br /><br /><br />     141: <br /><br /><br />     142:         protected static ProviderManager ProviderManager { get; set; }<br /><br /><br />     143:         protected static MappingManager MappingManager { get; set; }<br /><br /><br />     144: <br /><br /><br />     145:         #endregion<br /><br /><br />     146:     }<br /><br /><br />     147: }<br /><br /><br /><br />This is our main point of code that we are going to use to get our objects. We set it up, call Get, and it will return to us our object (with the appropriate items injected). One thing that you’ll notice is that there are a couple nonstandard C# calls in there (specifically the ForEach on the IEnumerable, IsNull, etc). These are all functions from the new utility library that I’m working on. I’ve been adding quite a bit to it, tons of extension methods, etc. So go and check out the repository as all of my code on here uses it (or at least the code on here uses a version of it). Plus any updates to the code can be found there also as I tend to forget the pages on this site. Anyway another thing you may notice is there isn’t much code here. Most of the actual work is going to be done in the ProviderManager and MappingManager.<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Providers.Interfaces;<br /><br /><br />      28: using Utilities.IoC.Providers.Scope;<br /><br /><br />      29: using Utilities.Reflection;<br /><br /><br />      30: using Utilities.Reflection.ExtensionMethods;<br /><br /><br />      31: using Utilities.DataTypes.ExtensionMethods;<br /><br /><br />      32: using System.Reflection;<br /><br /><br />      33: #endregion<br /><br /><br />      34: <br /><br /><br />      35: namespace Utilities.IoC.Providers<br /><br /><br />      36: {<br /><br /><br />      37:     /// andlt;summaryandgt;<br /><br /><br />      38:     /// Provider manager<br /><br /><br />      39:     /// andlt;/summaryandgt;<br /><br /><br />      40:     public class ProviderManager<br /><br /><br />      41:     {<br /><br /><br />      42:         #region Constructor<br /><br /><br />      43: <br /><br /><br />      44:         /// andlt;summaryandgt;<br /><br /><br />      45:         /// Constructor<br /><br /><br />      46:         /// andlt;/summaryandgt;<br /><br /><br />      47:         public ProviderManager()<br /><br /><br />      48:         {<br /><br /><br />      49:             Providers = new Listandlt;IProviderandgt;();<br /><br /><br />      50:             Providers.AddRange(typeof(ProviderManager).Assembly.GetObjectsandlt;IProviderandgt;());<br /><br /><br />      51:         }<br /><br /><br />      52: <br /><br /><br />      53:         #endregion<br /><br /><br />      54: <br /><br /><br />      55:         #region Functions<br /><br /><br />      56: <br /><br /><br />      57:         /// andlt;summaryandgt;<br /><br /><br />      58:         /// Sets up all providers found within the assembly specified<br /><br /><br />      59:         /// andlt;/summaryandgt;<br /><br /><br />      60:         /// andlt;param name=andquot;Assemblyandquot;andgt;Assembly to scanandlt;/paramandgt;<br /><br /><br />      61:         public void Setup(Assembly Assembly)<br /><br /><br />      62:         {<br /><br /><br />      63:             Providers.AddRange(Assembly.GetObjectsandlt;IProviderandgt;());<br /><br /><br />      64:         }<br /><br /><br />      65: <br /><br /><br />      66:         /// andlt;summaryandgt;<br /><br /><br />      67:         /// Gets the specified provider based on the scope specified<br /><br /><br />      68:         /// andlt;/summaryandgt;<br /><br /><br />      69:         /// andlt;param name=andquot;Scopeandquot;andgt;Scopeandlt;/paramandgt;<br /><br /><br />      70:         /// andlt;returnsandgt;The specified providerandlt;/returnsandgt;<br /><br /><br />      71:         public IProvider GetProvider(BaseScope Scope)<br /><br /><br />      72:         {<br /><br /><br />      73:             return Providers.FirstOrDefault(x =andgt; x.ProviderScope.Equals(Scope));<br /><br /><br />      74:         }<br /><br /><br />      75: <br /><br /><br />      76:         #endregion<br /><br /><br />      77: <br /><br /><br />      78:         #region Properties<br /><br /><br />      79: <br /><br /><br />      80:         protected virtual Listandlt;IProviderandgt; Providers { get; set; }<br /><br /><br />      81: <br /><br /><br />      82:         #endregion<br /><br /><br />      83:     }<br /><br /><br />      84: }<br /><br /><br /><br />The ProviderManager above holds a list of providers. These providers determine how to handle an implementation when you provide the system with one. The implementations actually determine how something is created. For instance, the code base only has one provider at present called Standard.<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Providers.Scope;<br /><br /><br />      28: using Utilities.IoC.Providers.Interfaces;<br /><br /><br />      29: using Utilities.IoC.Mappings;<br /><br /><br />      30: using Utilities.IoC.Providers.Implementations;<br /><br /><br />      31: #endregion<br /><br /><br />      32: <br /><br /><br />      33: namespace Utilities.IoC.Providers.DefaultProviders<br /><br /><br />      34: {<br /><br /><br />      35:     /// andlt;summaryandgt;<br /><br /><br />      36:     /// Standard provider<br /><br /><br />      37:     /// andlt;/summaryandgt;<br /><br /><br />      38:     public class Standard : IProvider<br /><br /><br />      39:     {<br /><br /><br />      40:         public IImplementation CreateImplementation(Type ImplementationType, MappingManager MappingManager)<br /><br /><br />      41:         {<br /><br /><br />      42:             return new Implementations.Standard(ImplementationType, MappingManager);<br /><br /><br />      43:         }<br /><br /><br />      44: <br /><br /><br />      45: <br /><br /><br />      46:         public BaseScope ProviderScope<br /><br /><br />      47:         {<br /><br /><br />      48:             get { return new StandardScope(); }<br /><br /><br />      49:         }<br /><br /><br />      50: <br /><br /><br />      51:         public IImplementation CreateImplementation(IImplementation Implementation, MappingManager MappingManager)<br /><br /><br />      52:         {<br /><br /><br />      53:             return CreateImplementation(Implementation.ReturnType, MappingManager);<br /><br /><br />      54:         }<br /><br /><br />      55: <br /><br /><br />      56:         public IImplementation CreateImplementationandlt;ImplementationTypeandgt;(Funcandlt;ImplementationTypeandgt; Implementation)<br /><br /><br />      57:         {<br /><br /><br />      58:             return new Delegateandlt;ImplementationTypeandgt;(Implementation);<br /><br /><br />      59:         }<br /><br /><br />      60:     }<br /><br /><br />      61: }<br /><br /><br /><br />This provider just creates a new implementation object (either a Delegate or Standard implementation depending) each time it’s fed anything. However we could have a provider called Singleton or something and have it return its own implementation types. We determine which provider to use in the ProviderManager based on something called Scopes:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: #endregion<br /><br /><br />      28: <br /><br /><br />      29: namespace Utilities.IoC.Providers.Scope<br /><br /><br />      30: {<br /><br /><br />      31:     /// andlt;summaryandgt;<br /><br /><br />      32:     /// Standard scope<br /><br /><br />      33:     /// andlt;/summaryandgt;<br /><br /><br />      34:     public class StandardScope : BaseScope<br /><br /><br />      35:     {<br /><br /><br />      36:         #region Constructor<br /><br /><br />      37: <br /><br /><br />      38:         public StandardScope()<br /><br /><br />      39:             : base()<br /><br /><br />      40:         {<br /><br /><br />      41:         }<br /><br /><br />      42: <br /><br /><br />      43:         #endregion<br /><br /><br />      44: <br /><br /><br />      45:         #region Properties<br /><br /><br />      46: <br /><br /><br />      47:         public override string Name { get { return andquot;Standardandquot;; } }<br /><br /><br />      48: <br /><br /><br />      49:         #endregion<br /><br /><br />      50:     }<br /><br /><br />      51: }<br /><br /><br /><br />As you can see, it’s just a holder of info. So for our Singleton provider example, we would need to create a Singleton scope and have it return that value so we know which to use. Anyway, the next bit is the actual implementations:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings;<br /><br /><br />      28: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      29: using System.Reflection;<br /><br /><br />      30: using Utilities.IoC.Mappings.Attributes;<br /><br /><br />      31: using Utilities.IoC.Providers.BaseClasses;<br /><br /><br />      32: using Utilities.DataTypes.ExtensionMethods;<br /><br /><br />      33: using Utilities.Reflection.ExtensionMethods;<br /><br /><br />      34: #endregion<br /><br /><br />      35: <br /><br /><br />      36: namespace Utilities.IoC.Providers.Implementations<br /><br /><br />      37: {<br /><br /><br />      38:     /// andlt;summaryandgt;<br /><br /><br />      39:     /// Standard implementation class<br /><br /><br />      40:     /// andlt;/summaryandgt;<br /><br /><br />      41:     public class Standard : BaseImplementation<br /><br /><br />      42:     {<br /><br /><br />      43:         #region Constructor<br /><br /><br />      44: <br /><br /><br />      45:         /// andlt;summaryandgt;<br /><br /><br />      46:         /// Constructor<br /><br /><br />      47:         /// andlt;/summaryandgt;<br /><br /><br />      48:         /// andlt;param name=andquot;ImplementationTypeandquot;andgt;Implementation typeandlt;/paramandgt;<br /><br /><br />      49:         /// andlt;param name=andquot;MappingManagerandquot;andgt;Mapping managerandlt;/paramandgt;<br /><br /><br />      50:         public Standard(Type ImplementationType, MappingManager MappingManager)<br /><br /><br />      51:         {<br /><br /><br />      52:             this.ReturnType = ImplementationType;<br /><br /><br />      53:             this.MappingManager = MappingManager;<br /><br /><br />      54:         }<br /><br /><br />      55: <br /><br /><br />      56:         #endregion<br /><br /><br />      57: <br /><br /><br />      58:         #region Functions<br /><br /><br />      59: <br /><br /><br />      60:         #region Create<br /><br /><br />      61: <br /><br /><br />      62:         public override object Create()<br /><br /><br />      63:         {<br /><br /><br />      64:             ConstructorInfo Constructor = Utils.ConstructorList.ChooseConstructor(ReturnType, MappingManager);<br /><br /><br />      65:             object Instance = CreateInstance(Constructor);<br /><br /><br />      66:             SetupProperties(Instance);<br /><br /><br />      67:             SetupMethods(Instance);<br /><br /><br />      68:             return Instance;<br /><br /><br />      69:         }<br /><br /><br />      70: <br /><br /><br />      71:         #endregion<br /><br /><br />      72: <br /><br /><br />      73:         #region SetupMethods<br /><br /><br />      74: <br /><br /><br />      75:         private void SetupMethods(object Instance)<br /><br /><br />      76:         {<br /><br /><br />      77:             if (Instance.IsNull())<br /><br /><br />      78:                 return;<br /><br /><br />      79:             foreach (MethodInfo Method in Instance.GetType().GetMethods().Where(x =andgt; IsInjectable(x)))<br /><br /><br />      80:                 Method.Invoke(Instance, Method.GetParameters().ForEach(x =andgt; CreateInstance(x)).ToArray());<br /><br /><br />      81:         }<br /><br /><br />      82: <br /><br /><br />      83:         #endregion<br /><br /><br />      84: <br /><br /><br />      85:         #region SetupProperties<br /><br /><br />      86: <br /><br /><br />      87:         private void SetupProperties(object Instance)<br /><br /><br />      88:         {<br /><br /><br />      89:             if (Instance.IsNull())<br /><br /><br />      90:                 return;<br /><br /><br />      91:             Instance.GetType()<br /><br /><br />      92:                 .GetProperties()<br /><br /><br />      93:                 .Where(x =andgt; IsInjectable(x))<br /><br /><br />      94:                 .ForEachandlt;PropertyInfoandgt;(x =andgt; Instance.SetProperty(x, CreateInstance(x)));<br /><br /><br />      95:         }<br /><br /><br />      96: <br /><br /><br />      97:         #endregion<br /><br /><br />      98: <br /><br /><br />      99:         #region IsInjectable<br /><br /><br />     100: <br /><br /><br />     101:         private bool IsInjectable(MethodInfo Method)<br /><br /><br />     102:         {<br /><br /><br />     103:             return IsInjectable(Method.GetCustomAttributes(false));<br /><br /><br />     104:         }<br /><br /><br />     105: <br /><br /><br />     106:         private bool IsInjectable(PropertyInfo Property)<br /><br /><br />     107:         {<br /><br /><br />     108:             return IsInjectable(Property.GetCustomAttributes(false));<br /><br /><br />     109:         }<br /><br /><br />     110: <br /><br /><br />     111:         private bool IsInjectable(object[] Attributes)<br /><br /><br />     112:         {<br /><br /><br />     113:             return Attributes.OfTypeandlt;Injectandgt;().Count() andgt; 0;<br /><br /><br />     114:         }<br /><br /><br />     115: <br /><br /><br />     116:         #endregion<br /><br /><br />     117: <br /><br /><br />     118:         #region CreateInstance<br /><br /><br />     119: <br /><br /><br />     120:         private object CreateInstance(ConstructorInfo Constructor)<br /><br /><br />     121:         {<br /><br /><br />     122:             if (Constructor.IsNull() || MappingManager.IsNull())<br /><br /><br />     123:                 return null;<br /><br /><br />     124:             Listandlt;objectandgt; ParameterValues = new Listandlt;objectandgt;();<br /><br /><br />     125:             Constructor.GetParameters().ForEachandlt;ParameterInfoandgt;(x =andgt; ParameterValues.Add(CreateInstance(x)));<br /><br /><br />     126:             return Constructor.Invoke(ParameterValues.ToArray());<br /><br /><br />     127:         }<br /><br /><br />     128: <br /><br /><br />     129:         private object CreateInstance(ParameterInfo Parameter)<br /><br /><br />     130:         {<br /><br /><br />     131:             return CreateInstance(Parameter.GetCustomAttributes(false), Parameter.ParameterType);<br /><br /><br />     132:         }<br /><br /><br />     133: <br /><br /><br />     134:         private object CreateInstance(PropertyInfo Property)<br /><br /><br />     135:         {<br /><br /><br />     136:             return CreateInstance(Property.GetCustomAttributes(false), Property.PropertyType);<br /><br /><br />     137:         }<br /><br /><br />     138: <br /><br /><br />     139:         private object CreateInstance(object[] Attributes, Type Type)<br /><br /><br />     140:         {<br /><br /><br />     141:             if (Attributes.Length andgt; 0)<br /><br /><br />     142:             {<br /><br /><br />     143:                 foreach (Attribute Attribute in Attributes)<br /><br /><br />     144:                 {<br /><br /><br />     145:                     object TempObject = GetObject(Type, Attribute.GetType());<br /><br /><br />     146:                     if (!TempObject.IsNull())<br /><br /><br />     147:                         return TempObject;<br /><br /><br />     148:                 }<br /><br /><br />     149:             }<br /><br /><br />     150:             return GetObject(Type);<br /><br /><br />     151:         }<br /><br /><br />     152: <br /><br /><br />     153:         #endregion<br /><br /><br />     154: <br /><br /><br />     155:         #region GetObject<br /><br /><br />     156: <br /><br /><br />     157:         private object GetObject(Type Type)<br /><br /><br />     158:         {<br /><br /><br />     159:             IMapping Mapping = MappingManager.GetMapping(Type);<br /><br /><br />     160:             return Mapping.IsNull() ? null : Mapping.Implementation.Create();<br /><br /><br />     161:         }<br /><br /><br />     162: <br /><br /><br />     163:         private object GetObject(Type Type, Type AttributeType)<br /><br /><br />     164:         {<br /><br /><br />     165:             IMapping Mapping = MappingManager.GetMapping(Type, AttributeType);<br /><br /><br />     166:             return Mapping.IsNull() ? null : Mapping.Implementation.Create();<br /><br /><br />     167:         }<br /><br /><br />     168: <br /><br /><br />     169:         #endregion<br /><br /><br />     170: <br /><br /><br />     171:         #endregion<br /><br /><br />     172: <br /><br /><br />     173:         #region Properties<br /><br /><br />     174: <br /><br /><br />     175:         /// andlt;summaryandgt;<br /><br /><br />     176:         /// Mapping manager<br /><br /><br />     177:         /// andlt;/summaryandgt;<br /><br /><br />     178:         protected virtual MappingManager MappingManager { get; set; }<br /><br /><br />     179: <br /><br /><br />     180:         #endregion<br /><br /><br />     181:     }<br /><br /><br />     182: }<br /><br /><br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Providers.BaseClasses;<br /><br /><br />      28: #endregion<br /><br /><br />      29: <br /><br /><br />      30: namespace Utilities.IoC.Providers.Implementations<br /><br /><br />      31: {<br /><br /><br />      32:     /// andlt;summaryandgt;<br /><br /><br />      33:     /// Delegate implementation<br /><br /><br />      34:     /// andlt;/summaryandgt;<br /><br /><br />      35:     /// andlt;typeparam name=andquot;Tandquot;andgt;Return type of the delegateandlt;/typeparamandgt;<br /><br /><br />      36:     public class Delegateandlt;Tandgt; : BaseImplementation<br /><br /><br />      37:     {<br /><br /><br />      38:         #region Constructor<br /><br /><br />      39: <br /><br /><br />      40:         /// andlt;summaryandgt;<br /><br /><br />      41:         /// Constructor<br /><br /><br />      42:         /// andlt;/summaryandgt;<br /><br /><br />      43:         /// andlt;param name=andquot;Implementationandquot;andgt;Implementation delegateandlt;/paramandgt;<br /><br /><br />      44:         public Delegate(Funcandlt;Tandgt; Implementation)<br /><br /><br />      45:         {<br /><br /><br />      46:             this.Implementation = Implementation;<br /><br /><br />      47:             ReturnType = typeof(T);<br /><br /><br />      48:         }<br /><br /><br />      49: <br /><br /><br />      50:         #endregion<br /><br /><br />      51: <br /><br /><br />      52:         #region Functions<br /><br /><br />      53: <br /><br /><br />      54:         /// andlt;summaryandgt;<br /><br /><br />      55:         /// Creates an object based on a delegate<br /><br /><br />      56:         /// andlt;/summaryandgt;<br /><br /><br />      57:         /// andlt;returnsandgt;An objectandlt;/returnsandgt;<br /><br /><br />      58:         public override object Create()<br /><br /><br />      59:         {<br /><br /><br />      60:             return Implementation();<br /><br /><br />      61:         }<br /><br /><br />      62: <br /><br /><br />      63:         #endregion<br /><br /><br />      64: <br /><br /><br />      65:         #region Properties<br /><br /><br />      66: <br /><br /><br />      67:         /// andlt;summaryandgt;<br /><br /><br />      68:         /// Delegate used to create objects<br /><br /><br />      69:         /// andlt;/summaryandgt;<br /><br /><br />      70:         protected virtual Funcandlt;Tandgt; Implementation { get; set; }<br /><br /><br />      71: <br /><br /><br />      72:         #endregion<br /><br /><br />      73:     }<br /><br /><br />      74: }<br /><br /><br /><br />You’ll notice that the Delegate implementation is a bit simpler. In this case you provide a Func and we just assume you know how you want an item created so we just return it. The standard implementation though is a bit more complicated.<br /><br />When we call the standard implementation’s Create function, it calls this little utility to determine which constructor to use:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using System.Reflection;<br /><br /><br />      28: using Utilities.IoC.Mappings;<br /><br /><br />      29: #endregion<br /><br /><br />      30: <br /><br /><br />      31: namespace Utilities.IoC.Utils<br /><br /><br />      32: {<br /><br /><br />      33:     public static class ConstructorList<br /><br /><br />      34:     {<br /><br /><br />      35:         public static ConstructorInfo ChooseConstructor(Type ImplementationType, MappingManager MappingManager)<br /><br /><br />      36:         {<br /><br /><br />      37:             ConstructorInfo[] Constructors = ImplementationType.GetConstructors();<br /><br /><br />      38:             int MaxValue = int.MinValue;<br /><br /><br />      39:             ConstructorInfo CurrentConstructor = null;<br /><br /><br />      40:             foreach (ConstructorInfo Constructor in Constructors)<br /><br /><br />      41:             {<br /><br /><br />      42:                 int Count = GetParameterCount(Constructor, MappingManager);<br /><br /><br />      43:                 if (Count andgt; MaxValue)<br /><br /><br />      44:                 {<br /><br /><br />      45:                     CurrentConstructor = Constructor;<br /><br /><br />      46:                     MaxValue = Count;<br /><br /><br />      47:                 }<br /><br /><br />      48:             }<br /><br /><br />      49:             return CurrentConstructor;<br /><br /><br />      50:         }<br /><br /><br />      51: <br /><br /><br />      52:         private static int GetParameterCount(ConstructorInfo Constructor, MappingManager MappingManager)<br /><br /><br />      53:         {<br /><br /><br />      54:             int Count = 0;<br /><br /><br />      55:             ParameterInfo[] Parameters = Constructor.GetParameters();<br /><br /><br />      56:             foreach (ParameterInfo Parameter in Parameters)<br /><br /><br />      57:             {<br /><br /><br />      58:                 bool Inject = true;<br /><br /><br />      59:                 object[] Attributes = Parameter.GetCustomAttributes(false);<br /><br /><br />      60:                 if (Attributes.Length andgt; 0)<br /><br /><br />      61:                 {<br /><br /><br />      62:                     foreach (Attribute Attribute in Attributes)<br /><br /><br />      63:                     {<br /><br /><br />      64:                         if (MappingManager.GetMapping(Parameter.ParameterType, Attribute.GetType()) != null)<br /><br /><br />      65:                         {<br /><br /><br />      66:                             ++Count;<br /><br /><br />      67:                             Inject = false;<br /><br /><br />      68:                             break;<br /><br /><br />      69:                         }<br /><br /><br />      70:                     }<br /><br /><br />      71:                 }<br /><br /><br />      72:                 if (Inject)<br /><br /><br />      73:                 {<br /><br /><br />      74:                     if (MappingManager.GetMapping(Parameter.ParameterType) != null)<br /><br /><br />      75:                         ++Count;<br /><br /><br />      76:                 }<br /><br /><br />      77:             }<br /><br /><br />      78:             if (Count == Parameters.Length)<br /><br /><br />      79:                 return Count;<br /><br /><br />      80:             return int.MinValue;<br /><br /><br />      81:         }<br /><br /><br />      82:     }<br /><br /><br />      83: }<br /><br /><br /><br />This bit of code simply determines which constructor has the most items that we know how to create and returns it. The Standard.Create function then takes that constructor and calls CreateInstance. This call determines the parameters of the constructor, and creates each one in turn using the MappingManager (we’ll get to that later). It then feeds the newly created items into the constructor and creates the object. After that it searches each method and each property to determine if they have been marked for injection also (note that this is done using an attribute called Inject). If it finds anything, it creates more objects in the same manner as the parameters for the constructor. Once it’s done with that, it returns the newly created object.<br /><br />So at this point we have our code to actually create our objects but we have nothing mapping it to anything. We can create but we don’t know when and we don’t know why. That’s where the MappingManager comes in.<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      28: using System.Reflection;<br /><br /><br />      29: using Utilities.IoC.Providers;<br /><br /><br />      30: using Utilities.Reflection.ExtensionMethods;<br /><br /><br />      31: using Utilities.IoC.Mappings.Internal_Classes;<br /><br /><br />      32: using Utilities.IoC.Mappings.BaseClasses;<br /><br /><br />      33: #endregion<br /><br /><br />      34: <br /><br /><br />      35: namespace Utilities.IoC.Mappings<br /><br /><br />      36: {<br /><br /><br />      37:     /// andlt;summaryandgt;<br /><br /><br />      38:     /// Mapping manager<br /><br /><br />      39:     /// andlt;/summaryandgt;<br /><br /><br />      40:     public class MappingManager<br /><br /><br />      41:     {<br /><br /><br />      42:         #region Constructor<br /><br /><br />      43: <br /><br /><br />      44:         /// andlt;summaryandgt;<br /><br /><br />      45:         /// Constructor<br /><br /><br />      46:         /// andlt;/summaryandgt;<br /><br /><br />      47:         public MappingManager(ProviderManager ProviderManager)<br /><br /><br />      48:         {<br /><br /><br />      49:             Modules = new Listandlt;IModuleandgt;();<br /><br /><br />      50:             Mappings = new Listandlt;IMappingandgt;();<br /><br /><br />      51:             this.ProviderManager = ProviderManager;<br /><br /><br />      52:         }<br /><br /><br />      53: <br /><br /><br />      54:         #endregion<br /><br /><br />      55: <br /><br /><br />      56:         #region Functions<br /><br /><br />      57: <br /><br /><br />      58:         /// andlt;summaryandgt;<br /><br /><br />      59:         /// Scans the assembly for mapping modules and creates them<br /><br /><br />      60:         /// andlt;/summaryandgt;<br /><br /><br />      61:         /// andlt;param name=andquot;ModuleAssemblyandquot;andgt;andlt;/paramandgt;<br /><br /><br />      62:         public void Setup(Assembly ModuleAssembly)<br /><br /><br />      63:         {<br /><br /><br />      64:             IEnumerableandlt;Typeandgt; Modules = ModuleAssembly.GetTypes(typeof(IModule));<br /><br /><br />      65:             Listandlt;IModuleandgt; TempModules = new Listandlt;IModuleandgt;();<br /><br /><br />      66:             foreach (Type Module in Modules)<br /><br /><br />      67:             {<br /><br /><br />      68:                 if (!Module.IsInterface andamp;andamp; !Module.IsAbstract)<br /><br /><br />      69:                     TempModules.Add((IModule)Module.Assembly.CreateInstance(Module.FullName));<br /><br /><br />      70:             }<br /><br /><br />      71:             foreach (IModule Module in TempModules)<br /><br /><br />      72:             {<br /><br /><br />      73:                 Module.Manager = this;<br /><br /><br />      74:                 Module.Setup();<br /><br /><br />      75:             }<br /><br /><br />      76:             this.Modules.AddRange(TempModules);<br /><br /><br />      77:         }<br /><br /><br />      78: <br /><br /><br />      79:         /// andlt;summaryandgt;<br /><br /><br />      80:         /// Creates a mapping object<br /><br /><br />      81:         /// andlt;/summaryandgt;<br /><br /><br />      82:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      83:         /// andlt;returnsandgt;a mapping objectandlt;/returnsandgt;<br /><br /><br />      84:         public IMapping CreateMapping(Type ServiceType)<br /><br /><br />      85:         {<br /><br /><br />      86:             IMapping Mapping = new Mapping(ServiceType, ProviderManager, this);<br /><br /><br />      87:             Mappings.Add(Mapping);<br /><br /><br />      88:             return Mapping;<br /><br /><br />      89:         }<br /><br /><br />      90: <br /><br /><br />      91:         /// andlt;summaryandgt;<br /><br /><br />      92:         /// Creates a mapping object<br /><br /><br />      93:         /// andlt;/summaryandgt;<br /><br /><br />      94:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      95:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />      96:         /// andlt;returnsandgt;A mapping objectandlt;/returnsandgt;<br /><br /><br />      97:         public IMapping CreateMapping(Type ServiceType, Type AttributeType)<br /><br /><br />      98:         {<br /><br /><br />      99:             IMapping Mapping = new Mapping(ServiceType, AttributeType, ProviderManager, this);<br /><br /><br />     100:             Mappings.Add(Mapping);<br /><br /><br />     101:             return Mapping;<br /><br /><br />     102:         }<br /><br /><br />     103: <br /><br /><br />     104:         /// andlt;summaryandgt;<br /><br /><br />     105:         /// Gets the mapping that matches this service type<br /><br /><br />     106:         /// andlt;/summaryandgt;<br /><br /><br />     107:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />     108:         /// andlt;returnsandgt;The mapping associated with this service typeandlt;/returnsandgt;<br /><br /><br />     109:         public IMapping GetMapping(Type ServiceType)<br /><br /><br />     110:         {<br /><br /><br />     111:             MappingKey Key = new MappingKey(ServiceType, null, ProviderManager, this);<br /><br /><br />     112:             return Mappings.Find(x =andgt; x.Equals(Key));<br /><br /><br />     113:         }<br /><br /><br />     114: <br /><br /><br />     115:         /// andlt;summaryandgt;<br /><br /><br />     116:         /// Gets the mapping that matches this service type and attribute type<br /><br /><br />     117:         /// andlt;/summaryandgt;<br /><br /><br />     118:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />     119:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />     120:         /// andlt;returnsandgt;The mapping associated with this service type and attribute typeandlt;/returnsandgt;<br /><br /><br />     121:         public IMapping GetMapping(Type ServiceType, Type AttributeType)<br /><br /><br />     122:         {<br /><br /><br />     123:             MappingKey Key = new MappingKey(ServiceType, AttributeType, ProviderManager, this);<br /><br /><br />     124:             return Mappings.Find(x =andgt; x.Equals(Key));<br /><br /><br />     125:         }<br /><br /><br />     126: <br /><br /><br />     127:         #endregion<br /><br /><br />     128: <br /><br /><br />     129:         #region Properties<br /><br /><br />     130: <br /><br /><br />     131:         /// andlt;summaryandgt;<br /><br /><br />     132:         /// Modules listing<br /><br /><br />     133:         /// andlt;/summaryandgt;<br /><br /><br />     134:         protected virtual Listandlt;IModuleandgt; Modules { get; set; }<br /><br /><br />     135: <br /><br /><br />     136:         /// andlt;summaryandgt;<br /><br /><br />     137:         /// Mapping listing<br /><br /><br />     138:         /// andlt;/summaryandgt;<br /><br /><br />     139:         protected virtual Listandlt;IMappingandgt; Mappings { get; set; }<br /><br /><br />     140: <br /><br /><br />     141:         /// andlt;summaryandgt;<br /><br /><br />     142:         /// Provider manager<br /><br /><br />     143:         /// andlt;/summaryandgt;<br /><br /><br />     144:         protected virtual ProviderManager ProviderManager { get; set; }<br /><br /><br />     145: <br /><br /><br />     146:         #endregion<br /><br /><br />     147:     }<br /><br /><br />     148: }<br /><br /><br /><br />The MappingManager is also a bit bare on implementation. All it does is holds a series of mappings and modules and creates them/returns them as necessary. A module is actually not defined inside the system itself. It’s what the end user would use to let the system know what mappings to use. It uses the following interface and base class:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: #endregion<br /><br /><br />      28: <br /><br /><br />      29: namespace Utilities.IoC.Mappings.Interfaces<br /><br /><br />      30: {<br /><br /><br />      31:     /// andlt;summaryandgt;<br /><br /><br />      32:     /// Mapping module interface<br /><br /><br />      33:     /// andlt;/summaryandgt;<br /><br /><br />      34:     public interface IModule<br /><br /><br />      35:     {<br /><br /><br />      36:         #region Functions<br /><br /><br />      37: <br /><br /><br />      38:         /// andlt;summaryandgt;<br /><br /><br />      39:         /// Called to setup the module (actual mapping occurs here)<br /><br /><br />      40:         /// andlt;/summaryandgt;<br /><br /><br />      41:         void Setup();<br /><br /><br />      42: <br /><br /><br />      43:         #endregion<br /><br /><br />      44: <br /><br /><br />      45:         #region Properties<br /><br /><br />      46: <br /><br /><br />      47:         MappingManager Manager { get; set; }<br /><br /><br />      48: <br /><br /><br />      49:         #endregion<br /><br /><br />      50:     }<br /><br /><br />      51: }<br /><br /><br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      28: #endregion<br /><br /><br />      29: <br /><br /><br />      30: namespace Utilities.IoC.Mappings.BaseClasses<br /><br /><br />      31: {<br /><br /><br />      32:     /// andlt;summaryandgt;<br /><br /><br />      33:     /// Base module class<br /><br /><br />      34:     /// andlt;/summaryandgt;<br /><br /><br />      35:     public abstract class BaseModule : IModule<br /><br /><br />      36:     {<br /><br /><br />      37:         #region Functions<br /><br /><br />      38: <br /><br /><br />      39:         public abstract void Setup();<br /><br /><br />      40: <br /><br /><br />      41:         /// andlt;summaryandgt;<br /><br /><br />      42:         /// Creates a mapping using a specific service type<br /><br /><br />      43:         /// andlt;/summaryandgt;<br /><br /><br />      44:         /// andlt;typeparam name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/typeparamandgt;<br /><br /><br />      45:         /// andlt;returnsandgt;A mapping objectandlt;/returnsandgt;<br /><br /><br />      46:         public virtual IMapping Mapandlt;ServiceTypeandgt;()<br /><br /><br />      47:         {<br /><br /><br />      48:             return Map(typeof(ServiceType));<br /><br /><br />      49:         }<br /><br /><br />      50: <br /><br /><br />      51:         /// andlt;summaryandgt;<br /><br /><br />      52:         /// Creates a mapping using a specific service type and attribute type<br /><br /><br />      53:         /// andlt;/summaryandgt;<br /><br /><br />      54:         /// andlt;typeparam name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/typeparamandgt;<br /><br /><br />      55:         /// andlt;typeparam name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/typeparamandgt;<br /><br /><br />      56:         /// andlt;returnsandgt;A mapping objectandlt;/returnsandgt;<br /><br /><br />      57:         public virtual IMapping Mapandlt;ServiceType, AttributeTypeandgt;()<br /><br /><br />      58:         {<br /><br /><br />      59:             return Map(typeof(ServiceType), typeof(AttributeType));<br /><br /><br />      60:         }<br /><br /><br />      61: <br /><br /><br />      62:         /// andlt;summaryandgt;<br /><br /><br />      63:         /// Creates a mapping using a specific service type<br /><br /><br />      64:         /// andlt;/summaryandgt;<br /><br /><br />      65:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      66:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />      67:         /// andlt;returnsandgt;A mapping objectandlt;/returnsandgt;<br /><br /><br />      68:         public virtual IMapping Map(Type ServiceType, Type AttributeType = null)<br /><br /><br />      69:         {<br /><br /><br />      70:             return Manager.CreateMapping(ServiceType, AttributeType);<br /><br /><br />      71:         }<br /><br /><br />      72: <br /><br /><br />      73:         #endregion<br /><br /><br />      74: <br /><br /><br />      75:         #region Properties<br /><br /><br />      76: <br /><br /><br />      77:         public virtual MappingManager Manager { get; set; }<br /><br /><br />      78: <br /><br /><br />      79:         #endregion<br /><br /><br />      80:     }<br /><br /><br />      81: }<br /><br /><br /><br />For example, in your code, you would define a module like this:<br /><br /><br />  <br />       1: public class Module : BaseModule<br /><br /><br />       2: {<br /><br /><br />       3:     public override void Setup()<br /><br /><br />       4:     {<br /><br /><br />       5:         Mapandlt;ITestInterfaceandgt;().Toandlt;TestClass1andgt;().SetScope(new StandardScope());<br /><br /><br />       6:         Mapandlt;TestClass1andgt;().Toandlt;TestClass1andgt;(() =andgt; new TestClass1());<br /><br /><br />       7:         Mapandlt;ITestInterface, MyAttributeandgt;().To(new TestImplementation());<br /><br /><br />       8:         Mapandlt;TestClass2andgt;().Toandlt;TestClass2andgt;();<br /><br /><br />       9:     }<br /><br /><br />      10: }<br /><br /><br /><br />This module defines four mappings that the system can use. A mapping is, as the name suggests, a mapping between a key type and what should be created when it encounters that type. For instance whenever I hit the interface ITestInterface, we return a TestClass1 object. The module can also define the scope for the object and sets the implementation used. In the example above the first item maps ITestInterface to TestClass1 and sets the scope to StandardScope. The third item maps ITestInterface items that have the MyAttribute attribute to the TestImplementation implementation. Whenever you call Map in a module, it creates and returns a Mapping class:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.BaseClasses;<br /><br /><br />      28: using Utilities.IoC.Providers;<br /><br /><br />      29: #endregion<br /><br /><br />      30: <br /><br /><br />      31: namespace Utilities.IoC.Mappings.Internal_Classes<br /><br /><br />      32: {<br /><br /><br />      33:     /// andlt;summaryandgt;<br /><br /><br />      34:     /// Mapping class<br /><br /><br />      35:     /// andlt;/summaryandgt;<br /><br /><br />      36:     public class Mapping : MappingKey<br /><br /><br />      37:     {<br /><br /><br />      38:         #region Constructors<br /><br /><br />      39: <br /><br /><br />      40:         /// andlt;summaryandgt;<br /><br /><br />      41:         /// Constructor<br /><br /><br />      42:         /// andlt;/summaryandgt;<br /><br /><br />      43:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      44:         public Mapping(Type ServiceType, ProviderManager ProviderManager, MappingManager MappingManager)<br /><br /><br />      45:             : base(ServiceType, null, ProviderManager, MappingManager)<br /><br /><br />      46:         {<br /><br /><br />      47:         }<br /><br /><br />      48: <br /><br /><br />      49:         /// andlt;summaryandgt;<br /><br /><br />      50:         /// Constructor<br /><br /><br />      51:         /// andlt;/summaryandgt;<br /><br /><br />      52:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      53:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />      54:         public Mapping(Type ServiceType, Type AttributeType, ProviderManager ProviderManager, MappingManager MappingManager)<br /><br /><br />      55:             : base(ServiceType, AttributeType, ProviderManager, MappingManager)<br /><br /><br />      56:         {<br /><br /><br />      57:         }<br /><br /><br />      58: <br /><br /><br />      59:         #endregion<br /><br /><br />      60:     }<br /><br /><br />      61: }<br /><br /><br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      28: using Utilities.IoC.Providers;<br /><br /><br />      29: #endregion<br /><br /><br />      30: <br /><br /><br />      31: namespace Utilities.IoC.Mappings.BaseClasses<br /><br /><br />      32: {<br /><br /><br />      33:     /// andlt;summaryandgt;<br /><br /><br />      34:     /// Mapping key<br /><br /><br />      35:     /// andlt;/summaryandgt;<br /><br /><br />      36:     public class MappingKey : BaseMapping<br /><br /><br />      37:     {<br /><br /><br />      38:         #region Constructor<br /><br /><br />      39: <br /><br /><br />      40:         public MappingKey(Type ServiceType, Type AttributeType, ProviderManager ProviderManager, MappingManager MappingManager)<br /><br /><br />      41:             : base(ServiceType, AttributeType, ProviderManager, MappingManager)<br /><br /><br />      42:         {<br /><br /><br />      43:         }<br /><br /><br />      44: <br /><br /><br />      45:         #endregion<br /><br /><br />      46: <br /><br /><br />      47:         #region Functions<br /><br /><br />      48: <br /><br /><br />      49:         public override bool Equals(object obj)<br /><br /><br />      50:         {<br /><br /><br />      51:             if (!(obj is IMapping))<br /><br /><br />      52:                 return false;<br /><br /><br />      53:             IMapping ObjectMapping = (IMapping)obj;<br /><br /><br />      54:             return ObjectMapping.AttributeType == AttributeType<br /><br /><br />      55:                 andamp;andamp; ObjectMapping.ServiceType == ServiceType;<br /><br /><br />      56:         }<br /><br /><br />      57: <br /><br /><br />      58:         public override int GetHashCode()<br /><br /><br />      59:         {<br /><br /><br />      60:             int AttributeHash = AttributeType == null ? 1 : AttributeType.GetHashCode();<br /><br /><br />      61:             int ServiceHash = ServiceType == null ? 1 : ServiceType.GetHashCode();<br /><br /><br />      62:             return ServiceHash * AttributeHash;<br /><br /><br />      63:         }<br /><br /><br />      64: <br /><br /><br />      65:         #endregion<br /><br /><br />      66:     }<br /><br /><br />      67: }<br /><br /><br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      28: using Utilities.IoC.Providers;<br /><br /><br />      29: using Utilities.IoC.Providers.Scope;<br /><br /><br />      30: using Utilities.IoC.Providers.Interfaces;<br /><br /><br />      31: #endregion<br /><br /><br />      32: <br /><br /><br />      33: namespace Utilities.IoC.Mappings.BaseClasses<br /><br /><br />      34: {<br /><br /><br />      35:     /// andlt;summaryandgt;<br /><br /><br />      36:     /// Base mapping<br /><br /><br />      37:     /// andlt;/summaryandgt;<br /><br /><br />      38:     public class BaseMapping : IMapping<br /><br /><br />      39:     {<br /><br /><br />      40:         #region Constructor<br /><br /><br />      41: <br /><br /><br />      42:         /// andlt;summaryandgt;<br /><br /><br />      43:         /// Constructor<br /><br /><br />      44:         /// andlt;/summaryandgt;<br /><br /><br />      45:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      46:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />      47:         public BaseMapping(Type ServiceType, Type AttributeType, ProviderManager ProviderManager, MappingManager MappingManager)<br /><br /><br />      48:         {<br /><br /><br />      49:             this.ServiceType = ServiceType;<br /><br /><br />      50:             this.AttributeType = AttributeType;<br /><br /><br />      51:             this.ProviderManager = ProviderManager;<br /><br /><br />      52:             this.MappingManager = MappingManager;<br /><br /><br />      53:             this.Scope = new StandardScope();<br /><br /><br />      54:         }<br /><br /><br />      55: <br /><br /><br />      56:         #endregion<br /><br /><br />      57: <br /><br /><br />      58:         #region Functions<br /><br /><br />      59: <br /><br /><br />      60:         public virtual IMapping Toandlt;ImplementationTypeandgt;()<br /><br /><br />      61:         {<br /><br /><br />      62:             return To(typeof(ImplementationType));<br /><br /><br />      63:         }<br /><br /><br />      64: <br /><br /><br />      65:         public virtual IMapping To(Type ImplementationType)<br /><br /><br />      66:         {<br /><br /><br />      67:             Implementation = ProviderManager.GetProvider(Scope).CreateImplementation(ImplementationType, MappingManager);<br /><br /><br />      68:             return this;<br /><br /><br />      69:         }<br /><br /><br />      70: <br /><br /><br />      71:         public virtual IMapping Toandlt;ImplementationTypeandgt;(Funcandlt;ImplementationTypeandgt; Implementation)<br /><br /><br />      72:         {<br /><br /><br />      73:             this.Implementation = ProviderManager.GetProvider(Scope).CreateImplementation(Implementation);<br /><br /><br />      74:             return this;<br /><br /><br />      75:         }<br /><br /><br />      76: <br /><br /><br />      77:         public virtual IMapping To(Providers.Interfaces.IImplementation Implementation)<br /><br /><br />      78:         {<br /><br /><br />      79:             this.Implementation = Implementation;<br /><br /><br />      80:             return this;<br /><br /><br />      81:         }<br /><br /><br />      82: <br /><br /><br />      83:         public virtual IMapping SetScope(BaseScope Scope)<br /><br /><br />      84:         {<br /><br /><br />      85:             this.Scope = Scope;<br /><br /><br />      86:             Implementation = ProviderManager.GetProvider(Scope).CreateImplementation(Implementation, MappingManager);<br /><br /><br />      87:             return this;<br /><br /><br />      88:         }<br /><br /><br />      89: <br /><br /><br />      90:         #endregion<br /><br /><br />      91: <br /><br /><br />      92:         #region Properties<br /><br /><br />      93: <br /><br /><br />      94:         public virtual Type ServiceType { get; protected set; }<br /><br /><br />      95:         public virtual Type AttributeType { get; protected set; }<br /><br /><br />      96:         public virtual BaseScope Scope { get; protected set; }<br /><br /><br />      97:         public virtual IImplementation Implementation { get; protected set; }<br /><br /><br />      98:         protected virtual ProviderManager ProviderManager { get; set; }<br /><br /><br />      99:         protected virtual MappingManager MappingManager { get; set; }<br /><br /><br />     100: <br /><br /><br />     101:         #endregion<br /><br /><br />     102:     }<br /><br /><br />     103: }<br /><br /><br /><br />The Mapping class is rather empty, the MappingKey actually defines the functions needed to determine which mapping is which. And the BaseMapping class holds the functions that set the scope, set the implementation, etc. And with that we’re done.<br /><br />We create our modules, which sets our mappings, which the system holds for us until we tell the manager to get us a specific object type. Once we do that, it assembles our object for us. It’s not that complicated really and not that much code either (the largest file tops out at 189 lines of code including comments). And with that we have ourselves a simple DI container.<br /><br />If you want updates, or find bugs, etc. check out the repository for the utility library (this is currently under the Utilities.IoC namespace). I’m terrible about updating my site but I update the code there whenever a bug is found. And hopefully I’ll finish my huge update to that library before too long (and it is going to contain a number of changes and additions). Anyway, take a look at the code and happy coding.]]></description>
<itunes:subtitle>Building an DI Container</itunes:subtitle><itunes:summary><![CDATA[It has been a while since I’ve written anything. To say the least things are hectic. Most of which, I can’t really talk about at this point (let’s just say that I’m working on a product for a sector of the business world. I think I can say that much, but not much more until it gets closer to release). Anyway, today I’m finally getting around to talking about one more item that I’ve added to my utility library. Specifically I’ve added a basic DI container (dependency injection).  Note that this next section is an over simplification and I’m tired so if it’s wrong, feel free to say so. Anyway, Dependency injection is a specific form of inversion of control. Inversion of control is when you invert the flow of a system. Instead of one central bit of code deciding how everything is run, it’s up to the individual pieces to know how to do the actual work. For instance, if I call an object factory to create a database connection for me, I don’t care how it’s created or how the connection is doing anything as long as it gets done. And dependency injection is just a specific form of IoC. Instead of hard coding our dependencies in each individual class, we allow someone to pass in the component that they want to use. You can actually do this manually (using a factory pattern, etc.) and still have a form of dependency injection. However you can also automate this process using one of the many dependency injectors out there (I personally like Ninject and based the code below on it). But where’s the fun in using someone else’s when all we have to do is spend an afternoon and build our own.             1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Providers;<br /><br /><br />      28: using Utilities.IoC.Mappings;<br /><br /><br />      29: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      30: using System.Reflection;<br /><br /><br />      31: using System.IO;<br /><br /><br />      32: using Utilities.IO.ExtensionMethods;<br /><br /><br />      33: using Utilities.Reflection.ExtensionMethods;<br /><br /><br />      34: using Utilities.DataTypes.ExtensionMethods;<br /><br /><br />      35: #endregion<br /><br /><br />      36: <br /><br /><br />      37: namespace Utilities.IoC<br /><br /><br />      38: {<br /><br /><br />      39:     /// andlt;summaryandgt;<br /><br /><br />      40:     /// Manager class<br /><br /><br />      41:     /// andlt;/summaryandgt;<br /><br /><br />      42:     public class Manager<br /><br /><br />      43:     {<br /><br /><br />      44:         #region Constructor<br /><br /><br />      45: <br /><br /><br />      46:         /// andlt;summaryandgt;<br /><br /><br />      47:         /// Constructor<br /><br /><br />      48:         /// andlt;/summaryandgt;<br /><br /><br />      49:         public Manager()<br /><br /><br />      50:         {<br /><br /><br />      51:             if (ProviderManager.IsNull())<br /><br /><br />      52:                 ProviderManager = new ProviderManager();<br /><br /><br />      53:             if (MappingManager.IsNull())<br /><br /><br />      54:                 MappingManager = new MappingManager(ProviderManager);<br /><br /><br />      55:         }<br /><br /><br />      56: <br /><br /><br />      57:         #endregion<br /><br /><br />      58: <br /><br /><br />      59:         #region Functions<br /><br /><br />      60: <br /><br /><br />      61:         /// andlt;summaryandgt;<br /><br /><br />      62:         /// Loads all mapping modules found within the assembly<br /><br /><br />      63:         /// andlt;/summaryandgt;<br /><br /><br />      64:         /// andlt;param name=andquot;ModuleAssemblyandquot;andgt;Module assemblyandlt;/paramandgt;<br /><br /><br />      65:         public void Setup(Assembly ModuleAssembly)<br /><br /><br />      66:         {<br /><br /><br />      67:             ProviderManager.Setup(ModuleAssembly);<br /><br /><br />      68:             MappingManager.Setup(ModuleAssembly);<br /><br /><br />      69:         }<br /><br /><br />      70: <br /><br /><br />      71:         /// andlt;summaryandgt;<br /><br /><br />      72:         /// Loads all mapping modules found within the assemblies<br /><br /><br />      73:         /// andlt;/summaryandgt;<br /><br /><br />      74:         /// andlt;param name=andquot;ModuleAssembliesandquot;andgt;Module assembliesandlt;/paramandgt;<br /><br /><br />      75:         public void Setup(IEnumerableandlt;Assemblyandgt; ModuleAssemblies)<br /><br /><br />      76:         {<br /><br /><br />      77:             ModuleAssemblies.ForEach(x =andgt; Setup(x));<br /><br /><br />      78:         }<br /><br /><br />      79: <br /><br /><br />      80:         /// andlt;summaryandgt;<br /><br /><br />      81:         /// Loads all mapping modules found within a specific directory<br /><br /><br />      82:         /// andlt;/summaryandgt;<br /><br /><br />      83:         /// andlt;param name=andquot;Directoryandquot;andgt;Directory to scan for modulesandlt;/paramandgt;<br /><br /><br />      84:         /// andlt;param name=andquot;RecursiveScanandquot;andgt;Determines if sub directories should be scannedandlt;/paramandgt;<br /><br /><br />      85:         public void Setup(string Directory, bool ScanSubDirectories = true)<br /><br /><br />      86:         {<br /><br /><br />      87:             Setup(new DirectoryInfo(Directory).LoadAssemblies(ScanSubDirectories));<br /><br /><br />      88:         }<br /><br /><br />      89: <br /><br /><br />      90:         /// andlt;summaryandgt;<br /><br /><br />      91:         /// Creates an object of the specified type<br /><br /><br />      92:         /// andlt;/summaryandgt;<br /><br /><br />      93:         /// andlt;typeparam name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/typeparamandgt;<br /><br /><br />      94:         /// andlt;returnsandgt;An object of the specified typeandlt;/returnsandgt;<br /><br /><br />      95:         public ServiceType Getandlt;ServiceTypeandgt;()<br /><br /><br />      96:         {<br /><br /><br />      97:             return (ServiceType)Get(typeof(ServiceType));<br /><br /><br />      98:         }<br /><br /><br />      99: <br /><br /><br />     100:         /// andlt;summaryandgt;<br /><br /><br />     101:         /// Creates an object of the specified type associated with the attribute type<br /><br /><br />     102:         /// andlt;/summaryandgt;<br /><br /><br />     103:         /// andlt;typeparam name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/typeparamandgt;<br /><br /><br />     104:         /// andlt;typeparam name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/typeparamandgt;<br /><br /><br />     105:         /// andlt;returnsandgt;An object of the specified typeandlt;/returnsandgt;<br /><br /><br />     106:         public ServiceType Getandlt;ServiceType, AttributeTypeandgt;()<br /><br /><br />     107:         {<br /><br /><br />     108:             return (ServiceType)Get(typeof(ServiceType), typeof(AttributeType));<br /><br /><br />     109:         }<br /><br /><br />     110: <br /><br /><br />     111:         /// andlt;summaryandgt;<br /><br /><br />     112:         /// Creates an object of the specified type<br /><br /><br />     113:         /// andlt;/summaryandgt;<br /><br /><br />     114:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />     115:         /// andlt;returnsandgt;An object of the specified typeandlt;/returnsandgt;<br /><br /><br />     116:         public object Get(Type ServiceType)<br /><br /><br />     117:         {<br /><br /><br />     118:             IMapping Mapping = MappingManager.GetMapping(ServiceType);<br /><br /><br />     119:             if (Mapping.IsNull())<br /><br /><br />     120:                 throw new ArgumentException(andquot;ServiceType not found in mappingsandquot;);<br /><br /><br />     121:             return Mapping.Implementation.Create();<br /><br /><br />     122:         }<br /><br /><br />     123: <br /><br /><br />     124:         /// andlt;summaryandgt;<br /><br /><br />     125:         /// Creates an object of the specified type associated with the attribute type<br /><br /><br />     126:         /// andlt;/summaryandgt;<br /><br /><br />     127:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />     128:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />     129:         /// andlt;returnsandgt;An object of the specified typeandlt;/returnsandgt;<br /><br /><br />     130:         public object Get(Type ServiceType, Type AttributeType)<br /><br /><br />     131:         {<br /><br /><br />     132:             IMapping Mapping = MappingManager.GetMapping(ServiceType, AttributeType);<br /><br /><br />     133:             if (Mapping.IsNull())<br /><br /><br />     134:                 throw new ArgumentException(andquot;ServiceType not found in mappingsandquot;);<br /><br /><br />     135:             return Mapping.Implementation.Create();<br /><br /><br />     136:         }<br /><br /><br />     137: <br /><br /><br />     138:         #endregion<br /><br /><br />     139: <br /><br /><br />     140:         #region Properties<br /><br /><br />     141: <br /><br /><br />     142:         protected static ProviderManager ProviderManager { get; set; }<br /><br /><br />     143:         protected static MappingManager MappingManager { get; set; }<br /><br /><br />     144: <br /><br /><br />     145:         #endregion<br /><br /><br />     146:     }<br /><br /><br />     147: }<br /><br /><br /><br />This is our main point of code that we are going to use to get our objects. We set it up, call Get, and it will return to us our object (with the appropriate items injected). One thing that you’ll notice is that there are a couple nonstandard C# calls in there (specifically the ForEach on the IEnumerable, IsNull, etc). These are all functions from the new utility library that I’m working on. I’ve been adding quite a bit to it, tons of extension methods, etc. So go and check out the repository as all of my code on here uses it (or at least the code on here uses a version of it). Plus any updates to the code can be found there also as I tend to forget the pages on this site. Anyway another thing you may notice is there isn’t much code here. Most of the actual work is going to be done in the ProviderManager and MappingManager.<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Providers.Interfaces;<br /><br /><br />      28: using Utilities.IoC.Providers.Scope;<br /><br /><br />      29: using Utilities.Reflection;<br /><br /><br />      30: using Utilities.Reflection.ExtensionMethods;<br /><br /><br />      31: using Utilities.DataTypes.ExtensionMethods;<br /><br /><br />      32: using System.Reflection;<br /><br /><br />      33: #endregion<br /><br /><br />      34: <br /><br /><br />      35: namespace Utilities.IoC.Providers<br /><br /><br />      36: {<br /><br /><br />      37:     /// andlt;summaryandgt;<br /><br /><br />      38:     /// Provider manager<br /><br /><br />      39:     /// andlt;/summaryandgt;<br /><br /><br />      40:     public class ProviderManager<br /><br /><br />      41:     {<br /><br /><br />      42:         #region Constructor<br /><br /><br />      43: <br /><br /><br />      44:         /// andlt;summaryandgt;<br /><br /><br />      45:         /// Constructor<br /><br /><br />      46:         /// andlt;/summaryandgt;<br /><br /><br />      47:         public ProviderManager()<br /><br /><br />      48:         {<br /><br /><br />      49:             Providers = new Listandlt;IProviderandgt;();<br /><br /><br />      50:             Providers.AddRange(typeof(ProviderManager).Assembly.GetObjectsandlt;IProviderandgt;());<br /><br /><br />      51:         }<br /><br /><br />      52: <br /><br /><br />      53:         #endregion<br /><br /><br />      54: <br /><br /><br />      55:         #region Functions<br /><br /><br />      56: <br /><br /><br />      57:         /// andlt;summaryandgt;<br /><br /><br />      58:         /// Sets up all providers found within the assembly specified<br /><br /><br />      59:         /// andlt;/summaryandgt;<br /><br /><br />      60:         /// andlt;param name=andquot;Assemblyandquot;andgt;Assembly to scanandlt;/paramandgt;<br /><br /><br />      61:         public void Setup(Assembly Assembly)<br /><br /><br />      62:         {<br /><br /><br />      63:             Providers.AddRange(Assembly.GetObjectsandlt;IProviderandgt;());<br /><br /><br />      64:         }<br /><br /><br />      65: <br /><br /><br />      66:         /// andlt;summaryandgt;<br /><br /><br />      67:         /// Gets the specified provider based on the scope specified<br /><br /><br />      68:         /// andlt;/summaryandgt;<br /><br /><br />      69:         /// andlt;param name=andquot;Scopeandquot;andgt;Scopeandlt;/paramandgt;<br /><br /><br />      70:         /// andlt;returnsandgt;The specified providerandlt;/returnsandgt;<br /><br /><br />      71:         public IProvider GetProvider(BaseScope Scope)<br /><br /><br />      72:         {<br /><br /><br />      73:             return Providers.FirstOrDefault(x =andgt; x.ProviderScope.Equals(Scope));<br /><br /><br />      74:         }<br /><br /><br />      75: <br /><br /><br />      76:         #endregion<br /><br /><br />      77: <br /><br /><br />      78:         #region Properties<br /><br /><br />      79: <br /><br /><br />      80:         protected virtual Listandlt;IProviderandgt; Providers { get; set; }<br /><br /><br />      81: <br /><br /><br />      82:         #endregion<br /><br /><br />      83:     }<br /><br /><br />      84: }<br /><br /><br /><br />The ProviderManager above holds a list of providers. These providers determine how to handle an implementation when you provide the system with one. The implementations actually determine how something is created. For instance, the code base only has one provider at present called Standard.<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Providers.Scope;<br /><br /><br />      28: using Utilities.IoC.Providers.Interfaces;<br /><br /><br />      29: using Utilities.IoC.Mappings;<br /><br /><br />      30: using Utilities.IoC.Providers.Implementations;<br /><br /><br />      31: #endregion<br /><br /><br />      32: <br /><br /><br />      33: namespace Utilities.IoC.Providers.DefaultProviders<br /><br /><br />      34: {<br /><br /><br />      35:     /// andlt;summaryandgt;<br /><br /><br />      36:     /// Standard provider<br /><br /><br />      37:     /// andlt;/summaryandgt;<br /><br /><br />      38:     public class Standard : IProvider<br /><br /><br />      39:     {<br /><br /><br />      40:         public IImplementation CreateImplementation(Type ImplementationType, MappingManager MappingManager)<br /><br /><br />      41:         {<br /><br /><br />      42:             return new Implementations.Standard(ImplementationType, MappingManager);<br /><br /><br />      43:         }<br /><br /><br />      44: <br /><br /><br />      45: <br /><br /><br />      46:         public BaseScope ProviderScope<br /><br /><br />      47:         {<br /><br /><br />      48:             get { return new StandardScope(); }<br /><br /><br />      49:         }<br /><br /><br />      50: <br /><br /><br />      51:         public IImplementation CreateImplementation(IImplementation Implementation, MappingManager MappingManager)<br /><br /><br />      52:         {<br /><br /><br />      53:             return CreateImplementation(Implementation.ReturnType, MappingManager);<br /><br /><br />      54:         }<br /><br /><br />      55: <br /><br /><br />      56:         public IImplementation CreateImplementationandlt;ImplementationTypeandgt;(Funcandlt;ImplementationTypeandgt; Implementation)<br /><br /><br />      57:         {<br /><br /><br />      58:             return new Delegateandlt;ImplementationTypeandgt;(Implementation);<br /><br /><br />      59:         }<br /><br /><br />      60:     }<br /><br /><br />      61: }<br /><br /><br /><br />This provider just creates a new implementation object (either a Delegate or Standard implementation depending) each time it’s fed anything. However we could have a provider called Singleton or something and have it return its own implementation types. We determine which provider to use in the ProviderManager based on something called Scopes:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: #endregion<br /><br /><br />      28: <br /><br /><br />      29: namespace Utilities.IoC.Providers.Scope<br /><br /><br />      30: {<br /><br /><br />      31:     /// andlt;summaryandgt;<br /><br /><br />      32:     /// Standard scope<br /><br /><br />      33:     /// andlt;/summaryandgt;<br /><br /><br />      34:     public class StandardScope : BaseScope<br /><br /><br />      35:     {<br /><br /><br />      36:         #region Constructor<br /><br /><br />      37: <br /><br /><br />      38:         public StandardScope()<br /><br /><br />      39:             : base()<br /><br /><br />      40:         {<br /><br /><br />      41:         }<br /><br /><br />      42: <br /><br /><br />      43:         #endregion<br /><br /><br />      44: <br /><br /><br />      45:         #region Properties<br /><br /><br />      46: <br /><br /><br />      47:         public override string Name { get { return andquot;Standardandquot;; } }<br /><br /><br />      48: <br /><br /><br />      49:         #endregion<br /><br /><br />      50:     }<br /><br /><br />      51: }<br /><br /><br /><br />As you can see, it’s just a holder of info. So for our Singleton provider example, we would need to create a Singleton scope and have it return that value so we know which to use. Anyway, the next bit is the actual implementations:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings;<br /><br /><br />      28: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      29: using System.Reflection;<br /><br /><br />      30: using Utilities.IoC.Mappings.Attributes;<br /><br /><br />      31: using Utilities.IoC.Providers.BaseClasses;<br /><br /><br />      32: using Utilities.DataTypes.ExtensionMethods;<br /><br /><br />      33: using Utilities.Reflection.ExtensionMethods;<br /><br /><br />      34: #endregion<br /><br /><br />      35: <br /><br /><br />      36: namespace Utilities.IoC.Providers.Implementations<br /><br /><br />      37: {<br /><br /><br />      38:     /// andlt;summaryandgt;<br /><br /><br />      39:     /// Standard implementation class<br /><br /><br />      40:     /// andlt;/summaryandgt;<br /><br /><br />      41:     public class Standard : BaseImplementation<br /><br /><br />      42:     {<br /><br /><br />      43:         #region Constructor<br /><br /><br />      44: <br /><br /><br />      45:         /// andlt;summaryandgt;<br /><br /><br />      46:         /// Constructor<br /><br /><br />      47:         /// andlt;/summaryandgt;<br /><br /><br />      48:         /// andlt;param name=andquot;ImplementationTypeandquot;andgt;Implementation typeandlt;/paramandgt;<br /><br /><br />      49:         /// andlt;param name=andquot;MappingManagerandquot;andgt;Mapping managerandlt;/paramandgt;<br /><br /><br />      50:         public Standard(Type ImplementationType, MappingManager MappingManager)<br /><br /><br />      51:         {<br /><br /><br />      52:             this.ReturnType = ImplementationType;<br /><br /><br />      53:             this.MappingManager = MappingManager;<br /><br /><br />      54:         }<br /><br /><br />      55: <br /><br /><br />      56:         #endregion<br /><br /><br />      57: <br /><br /><br />      58:         #region Functions<br /><br /><br />      59: <br /><br /><br />      60:         #region Create<br /><br /><br />      61: <br /><br /><br />      62:         public override object Create()<br /><br /><br />      63:         {<br /><br /><br />      64:             ConstructorInfo Constructor = Utils.ConstructorList.ChooseConstructor(ReturnType, MappingManager);<br /><br /><br />      65:             object Instance = CreateInstance(Constructor);<br /><br /><br />      66:             SetupProperties(Instance);<br /><br /><br />      67:             SetupMethods(Instance);<br /><br /><br />      68:             return Instance;<br /><br /><br />      69:         }<br /><br /><br />      70: <br /><br /><br />      71:         #endregion<br /><br /><br />      72: <br /><br /><br />      73:         #region SetupMethods<br /><br /><br />      74: <br /><br /><br />      75:         private void SetupMethods(object Instance)<br /><br /><br />      76:         {<br /><br /><br />      77:             if (Instance.IsNull())<br /><br /><br />      78:                 return;<br /><br /><br />      79:             foreach (MethodInfo Method in Instance.GetType().GetMethods().Where(x =andgt; IsInjectable(x)))<br /><br /><br />      80:                 Method.Invoke(Instance, Method.GetParameters().ForEach(x =andgt; CreateInstance(x)).ToArray());<br /><br /><br />      81:         }<br /><br /><br />      82: <br /><br /><br />      83:         #endregion<br /><br /><br />      84: <br /><br /><br />      85:         #region SetupProperties<br /><br /><br />      86: <br /><br /><br />      87:         private void SetupProperties(object Instance)<br /><br /><br />      88:         {<br /><br /><br />      89:             if (Instance.IsNull())<br /><br /><br />      90:                 return;<br /><br /><br />      91:             Instance.GetType()<br /><br /><br />      92:                 .GetProperties()<br /><br /><br />      93:                 .Where(x =andgt; IsInjectable(x))<br /><br /><br />      94:                 .ForEachandlt;PropertyInfoandgt;(x =andgt; Instance.SetProperty(x, CreateInstance(x)));<br /><br /><br />      95:         }<br /><br /><br />      96: <br /><br /><br />      97:         #endregion<br /><br /><br />      98: <br /><br /><br />      99:         #region IsInjectable<br /><br /><br />     100: <br /><br /><br />     101:         private bool IsInjectable(MethodInfo Method)<br /><br /><br />     102:         {<br /><br /><br />     103:             return IsInjectable(Method.GetCustomAttributes(false));<br /><br /><br />     104:         }<br /><br /><br />     105: <br /><br /><br />     106:         private bool IsInjectable(PropertyInfo Property)<br /><br /><br />     107:         {<br /><br /><br />     108:             return IsInjectable(Property.GetCustomAttributes(false));<br /><br /><br />     109:         }<br /><br /><br />     110: <br /><br /><br />     111:         private bool IsInjectable(object[] Attributes)<br /><br /><br />     112:         {<br /><br /><br />     113:             return Attributes.OfTypeandlt;Injectandgt;().Count() andgt; 0;<br /><br /><br />     114:         }<br /><br /><br />     115: <br /><br /><br />     116:         #endregion<br /><br /><br />     117: <br /><br /><br />     118:         #region CreateInstance<br /><br /><br />     119: <br /><br /><br />     120:         private object CreateInstance(ConstructorInfo Constructor)<br /><br /><br />     121:         {<br /><br /><br />     122:             if (Constructor.IsNull() || MappingManager.IsNull())<br /><br /><br />     123:                 return null;<br /><br /><br />     124:             Listandlt;objectandgt; ParameterValues = new Listandlt;objectandgt;();<br /><br /><br />     125:             Constructor.GetParameters().ForEachandlt;ParameterInfoandgt;(x =andgt; ParameterValues.Add(CreateInstance(x)));<br /><br /><br />     126:             return Constructor.Invoke(ParameterValues.ToArray());<br /><br /><br />     127:         }<br /><br /><br />     128: <br /><br /><br />     129:         private object CreateInstance(ParameterInfo Parameter)<br /><br /><br />     130:         {<br /><br /><br />     131:             return CreateInstance(Parameter.GetCustomAttributes(false), Parameter.ParameterType);<br /><br /><br />     132:         }<br /><br /><br />     133: <br /><br /><br />     134:         private object CreateInstance(PropertyInfo Property)<br /><br /><br />     135:         {<br /><br /><br />     136:             return CreateInstance(Property.GetCustomAttributes(false), Property.PropertyType);<br /><br /><br />     137:         }<br /><br /><br />     138: <br /><br /><br />     139:         private object CreateInstance(object[] Attributes, Type Type)<br /><br /><br />     140:         {<br /><br /><br />     141:             if (Attributes.Length andgt; 0)<br /><br /><br />     142:             {<br /><br /><br />     143:                 foreach (Attribute Attribute in Attributes)<br /><br /><br />     144:                 {<br /><br /><br />     145:                     object TempObject = GetObject(Type, Attribute.GetType());<br /><br /><br />     146:                     if (!TempObject.IsNull())<br /><br /><br />     147:                         return TempObject;<br /><br /><br />     148:                 }<br /><br /><br />     149:             }<br /><br /><br />     150:             return GetObject(Type);<br /><br /><br />     151:         }<br /><br /><br />     152: <br /><br /><br />     153:         #endregion<br /><br /><br />     154: <br /><br /><br />     155:         #region GetObject<br /><br /><br />     156: <br /><br /><br />     157:         private object GetObject(Type Type)<br /><br /><br />     158:         {<br /><br /><br />     159:             IMapping Mapping = MappingManager.GetMapping(Type);<br /><br /><br />     160:             return Mapping.IsNull() ? null : Mapping.Implementation.Create();<br /><br /><br />     161:         }<br /><br /><br />     162: <br /><br /><br />     163:         private object GetObject(Type Type, Type AttributeType)<br /><br /><br />     164:         {<br /><br /><br />     165:             IMapping Mapping = MappingManager.GetMapping(Type, AttributeType);<br /><br /><br />     166:             return Mapping.IsNull() ? null : Mapping.Implementation.Create();<br /><br /><br />     167:         }<br /><br /><br />     168: <br /><br /><br />     169:         #endregion<br /><br /><br />     170: <br /><br /><br />     171:         #endregion<br /><br /><br />     172: <br /><br /><br />     173:         #region Properties<br /><br /><br />     174: <br /><br /><br />     175:         /// andlt;summaryandgt;<br /><br /><br />     176:         /// Mapping manager<br /><br /><br />     177:         /// andlt;/summaryandgt;<br /><br /><br />     178:         protected virtual MappingManager MappingManager { get; set; }<br /><br /><br />     179: <br /><br /><br />     180:         #endregion<br /><br /><br />     181:     }<br /><br /><br />     182: }<br /><br /><br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Providers.BaseClasses;<br /><br /><br />      28: #endregion<br /><br /><br />      29: <br /><br /><br />      30: namespace Utilities.IoC.Providers.Implementations<br /><br /><br />      31: {<br /><br /><br />      32:     /// andlt;summaryandgt;<br /><br /><br />      33:     /// Delegate implementation<br /><br /><br />      34:     /// andlt;/summaryandgt;<br /><br /><br />      35:     /// andlt;typeparam name=andquot;Tandquot;andgt;Return type of the delegateandlt;/typeparamandgt;<br /><br /><br />      36:     public class Delegateandlt;Tandgt; : BaseImplementation<br /><br /><br />      37:     {<br /><br /><br />      38:         #region Constructor<br /><br /><br />      39: <br /><br /><br />      40:         /// andlt;summaryandgt;<br /><br /><br />      41:         /// Constructor<br /><br /><br />      42:         /// andlt;/summaryandgt;<br /><br /><br />      43:         /// andlt;param name=andquot;Implementationandquot;andgt;Implementation delegateandlt;/paramandgt;<br /><br /><br />      44:         public Delegate(Funcandlt;Tandgt; Implementation)<br /><br /><br />      45:         {<br /><br /><br />      46:             this.Implementation = Implementation;<br /><br /><br />      47:             ReturnType = typeof(T);<br /><br /><br />      48:         }<br /><br /><br />      49: <br /><br /><br />      50:         #endregion<br /><br /><br />      51: <br /><br /><br />      52:         #region Functions<br /><br /><br />      53: <br /><br /><br />      54:         /// andlt;summaryandgt;<br /><br /><br />      55:         /// Creates an object based on a delegate<br /><br /><br />      56:         /// andlt;/summaryandgt;<br /><br /><br />      57:         /// andlt;returnsandgt;An objectandlt;/returnsandgt;<br /><br /><br />      58:         public override object Create()<br /><br /><br />      59:         {<br /><br /><br />      60:             return Implementation();<br /><br /><br />      61:         }<br /><br /><br />      62: <br /><br /><br />      63:         #endregion<br /><br /><br />      64: <br /><br /><br />      65:         #region Properties<br /><br /><br />      66: <br /><br /><br />      67:         /// andlt;summaryandgt;<br /><br /><br />      68:         /// Delegate used to create objects<br /><br /><br />      69:         /// andlt;/summaryandgt;<br /><br /><br />      70:         protected virtual Funcandlt;Tandgt; Implementation { get; set; }<br /><br /><br />      71: <br /><br /><br />      72:         #endregion<br /><br /><br />      73:     }<br /><br /><br />      74: }<br /><br /><br /><br />You’ll notice that the Delegate implementation is a bit simpler. In this case you provide a Func and we just assume you know how you want an item created so we just return it. The standard implementation though is a bit more complicated.<br /><br />When we call the standard implementation’s Create function, it calls this little utility to determine which constructor to use:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using System.Reflection;<br /><br /><br />      28: using Utilities.IoC.Mappings;<br /><br /><br />      29: #endregion<br /><br /><br />      30: <br /><br /><br />      31: namespace Utilities.IoC.Utils<br /><br /><br />      32: {<br /><br /><br />      33:     public static class ConstructorList<br /><br /><br />      34:     {<br /><br /><br />      35:         public static ConstructorInfo ChooseConstructor(Type ImplementationType, MappingManager MappingManager)<br /><br /><br />      36:         {<br /><br /><br />      37:             ConstructorInfo[] Constructors = ImplementationType.GetConstructors();<br /><br /><br />      38:             int MaxValue = int.MinValue;<br /><br /><br />      39:             ConstructorInfo CurrentConstructor = null;<br /><br /><br />      40:             foreach (ConstructorInfo Constructor in Constructors)<br /><br /><br />      41:             {<br /><br /><br />      42:                 int Count = GetParameterCount(Constructor, MappingManager);<br /><br /><br />      43:                 if (Count andgt; MaxValue)<br /><br /><br />      44:                 {<br /><br /><br />      45:                     CurrentConstructor = Constructor;<br /><br /><br />      46:                     MaxValue = Count;<br /><br /><br />      47:                 }<br /><br /><br />      48:             }<br /><br /><br />      49:             return CurrentConstructor;<br /><br /><br />      50:         }<br /><br /><br />      51: <br /><br /><br />      52:         private static int GetParameterCount(ConstructorInfo Constructor, MappingManager MappingManager)<br /><br /><br />      53:         {<br /><br /><br />      54:             int Count = 0;<br /><br /><br />      55:             ParameterInfo[] Parameters = Constructor.GetParameters();<br /><br /><br />      56:             foreach (ParameterInfo Parameter in Parameters)<br /><br /><br />      57:             {<br /><br /><br />      58:                 bool Inject = true;<br /><br /><br />      59:                 object[] Attributes = Parameter.GetCustomAttributes(false);<br /><br /><br />      60:                 if (Attributes.Length andgt; 0)<br /><br /><br />      61:                 {<br /><br /><br />      62:                     foreach (Attribute Attribute in Attributes)<br /><br /><br />      63:                     {<br /><br /><br />      64:                         if (MappingManager.GetMapping(Parameter.ParameterType, Attribute.GetType()) != null)<br /><br /><br />      65:                         {<br /><br /><br />      66:                             ++Count;<br /><br /><br />      67:                             Inject = false;<br /><br /><br />      68:                             break;<br /><br /><br />      69:                         }<br /><br /><br />      70:                     }<br /><br /><br />      71:                 }<br /><br /><br />      72:                 if (Inject)<br /><br /><br />      73:                 {<br /><br /><br />      74:                     if (MappingManager.GetMapping(Parameter.ParameterType) != null)<br /><br /><br />      75:                         ++Count;<br /><br /><br />      76:                 }<br /><br /><br />      77:             }<br /><br /><br />      78:             if (Count == Parameters.Length)<br /><br /><br />      79:                 return Count;<br /><br /><br />      80:             return int.MinValue;<br /><br /><br />      81:         }<br /><br /><br />      82:     }<br /><br /><br />      83: }<br /><br /><br /><br />This bit of code simply determines which constructor has the most items that we know how to create and returns it. The Standard.Create function then takes that constructor and calls CreateInstance. This call determines the parameters of the constructor, and creates each one in turn using the MappingManager (we’ll get to that later). It then feeds the newly created items into the constructor and creates the object. After that it searches each method and each property to determine if they have been marked for injection also (note that this is done using an attribute called Inject). If it finds anything, it creates more objects in the same manner as the parameters for the constructor. Once it’s done with that, it returns the newly created object.<br /><br />So at this point we have our code to actually create our objects but we have nothing mapping it to anything. We can create but we don’t know when and we don’t know why. That’s where the MappingManager comes in.<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      28: using System.Reflection;<br /><br /><br />      29: using Utilities.IoC.Providers;<br /><br /><br />      30: using Utilities.Reflection.ExtensionMethods;<br /><br /><br />      31: using Utilities.IoC.Mappings.Internal_Classes;<br /><br /><br />      32: using Utilities.IoC.Mappings.BaseClasses;<br /><br /><br />      33: #endregion<br /><br /><br />      34: <br /><br /><br />      35: namespace Utilities.IoC.Mappings<br /><br /><br />      36: {<br /><br /><br />      37:     /// andlt;summaryandgt;<br /><br /><br />      38:     /// Mapping manager<br /><br /><br />      39:     /// andlt;/summaryandgt;<br /><br /><br />      40:     public class MappingManager<br /><br /><br />      41:     {<br /><br /><br />      42:         #region Constructor<br /><br /><br />      43: <br /><br /><br />      44:         /// andlt;summaryandgt;<br /><br /><br />      45:         /// Constructor<br /><br /><br />      46:         /// andlt;/summaryandgt;<br /><br /><br />      47:         public MappingManager(ProviderManager ProviderManager)<br /><br /><br />      48:         {<br /><br /><br />      49:             Modules = new Listandlt;IModuleandgt;();<br /><br /><br />      50:             Mappings = new Listandlt;IMappingandgt;();<br /><br /><br />      51:             this.ProviderManager = ProviderManager;<br /><br /><br />      52:         }<br /><br /><br />      53: <br /><br /><br />      54:         #endregion<br /><br /><br />      55: <br /><br /><br />      56:         #region Functions<br /><br /><br />      57: <br /><br /><br />      58:         /// andlt;summaryandgt;<br /><br /><br />      59:         /// Scans the assembly for mapping modules and creates them<br /><br /><br />      60:         /// andlt;/summaryandgt;<br /><br /><br />      61:         /// andlt;param name=andquot;ModuleAssemblyandquot;andgt;andlt;/paramandgt;<br /><br /><br />      62:         public void Setup(Assembly ModuleAssembly)<br /><br /><br />      63:         {<br /><br /><br />      64:             IEnumerableandlt;Typeandgt; Modules = ModuleAssembly.GetTypes(typeof(IModule));<br /><br /><br />      65:             Listandlt;IModuleandgt; TempModules = new Listandlt;IModuleandgt;();<br /><br /><br />      66:             foreach (Type Module in Modules)<br /><br /><br />      67:             {<br /><br /><br />      68:                 if (!Module.IsInterface andamp;andamp; !Module.IsAbstract)<br /><br /><br />      69:                     TempModules.Add((IModule)Module.Assembly.CreateInstance(Module.FullName));<br /><br /><br />      70:             }<br /><br /><br />      71:             foreach (IModule Module in TempModules)<br /><br /><br />      72:             {<br /><br /><br />      73:                 Module.Manager = this;<br /><br /><br />      74:                 Module.Setup();<br /><br /><br />      75:             }<br /><br /><br />      76:             this.Modules.AddRange(TempModules);<br /><br /><br />      77:         }<br /><br /><br />      78: <br /><br /><br />      79:         /// andlt;summaryandgt;<br /><br /><br />      80:         /// Creates a mapping object<br /><br /><br />      81:         /// andlt;/summaryandgt;<br /><br /><br />      82:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      83:         /// andlt;returnsandgt;a mapping objectandlt;/returnsandgt;<br /><br /><br />      84:         public IMapping CreateMapping(Type ServiceType)<br /><br /><br />      85:         {<br /><br /><br />      86:             IMapping Mapping = new Mapping(ServiceType, ProviderManager, this);<br /><br /><br />      87:             Mappings.Add(Mapping);<br /><br /><br />      88:             return Mapping;<br /><br /><br />      89:         }<br /><br /><br />      90: <br /><br /><br />      91:         /// andlt;summaryandgt;<br /><br /><br />      92:         /// Creates a mapping object<br /><br /><br />      93:         /// andlt;/summaryandgt;<br /><br /><br />      94:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      95:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />      96:         /// andlt;returnsandgt;A mapping objectandlt;/returnsandgt;<br /><br /><br />      97:         public IMapping CreateMapping(Type ServiceType, Type AttributeType)<br /><br /><br />      98:         {<br /><br /><br />      99:             IMapping Mapping = new Mapping(ServiceType, AttributeType, ProviderManager, this);<br /><br /><br />     100:             Mappings.Add(Mapping);<br /><br /><br />     101:             return Mapping;<br /><br /><br />     102:         }<br /><br /><br />     103: <br /><br /><br />     104:         /// andlt;summaryandgt;<br /><br /><br />     105:         /// Gets the mapping that matches this service type<br /><br /><br />     106:         /// andlt;/summaryandgt;<br /><br /><br />     107:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />     108:         /// andlt;returnsandgt;The mapping associated with this service typeandlt;/returnsandgt;<br /><br /><br />     109:         public IMapping GetMapping(Type ServiceType)<br /><br /><br />     110:         {<br /><br /><br />     111:             MappingKey Key = new MappingKey(ServiceType, null, ProviderManager, this);<br /><br /><br />     112:             return Mappings.Find(x =andgt; x.Equals(Key));<br /><br /><br />     113:         }<br /><br /><br />     114: <br /><br /><br />     115:         /// andlt;summaryandgt;<br /><br /><br />     116:         /// Gets the mapping that matches this service type and attribute type<br /><br /><br />     117:         /// andlt;/summaryandgt;<br /><br /><br />     118:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />     119:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />     120:         /// andlt;returnsandgt;The mapping associated with this service type and attribute typeandlt;/returnsandgt;<br /><br /><br />     121:         public IMapping GetMapping(Type ServiceType, Type AttributeType)<br /><br /><br />     122:         {<br /><br /><br />     123:             MappingKey Key = new MappingKey(ServiceType, AttributeType, ProviderManager, this);<br /><br /><br />     124:             return Mappings.Find(x =andgt; x.Equals(Key));<br /><br /><br />     125:         }<br /><br /><br />     126: <br /><br /><br />     127:         #endregion<br /><br /><br />     128: <br /><br /><br />     129:         #region Properties<br /><br /><br />     130: <br /><br /><br />     131:         /// andlt;summaryandgt;<br /><br /><br />     132:         /// Modules listing<br /><br /><br />     133:         /// andlt;/summaryandgt;<br /><br /><br />     134:         protected virtual Listandlt;IModuleandgt; Modules { get; set; }<br /><br /><br />     135: <br /><br /><br />     136:         /// andlt;summaryandgt;<br /><br /><br />     137:         /// Mapping listing<br /><br /><br />     138:         /// andlt;/summaryandgt;<br /><br /><br />     139:         protected virtual Listandlt;IMappingandgt; Mappings { get; set; }<br /><br /><br />     140: <br /><br /><br />     141:         /// andlt;summaryandgt;<br /><br /><br />     142:         /// Provider manager<br /><br /><br />     143:         /// andlt;/summaryandgt;<br /><br /><br />     144:         protected virtual ProviderManager ProviderManager { get; set; }<br /><br /><br />     145: <br /><br /><br />     146:         #endregion<br /><br /><br />     147:     }<br /><br /><br />     148: }<br /><br /><br /><br />The MappingManager is also a bit bare on implementation. All it does is holds a series of mappings and modules and creates them/returns them as necessary. A module is actually not defined inside the system itself. It’s what the end user would use to let the system know what mappings to use. It uses the following interface and base class:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: #endregion<br /><br /><br />      28: <br /><br /><br />      29: namespace Utilities.IoC.Mappings.Interfaces<br /><br /><br />      30: {<br /><br /><br />      31:     /// andlt;summaryandgt;<br /><br /><br />      32:     /// Mapping module interface<br /><br /><br />      33:     /// andlt;/summaryandgt;<br /><br /><br />      34:     public interface IModule<br /><br /><br />      35:     {<br /><br /><br />      36:         #region Functions<br /><br /><br />      37: <br /><br /><br />      38:         /// andlt;summaryandgt;<br /><br /><br />      39:         /// Called to setup the module (actual mapping occurs here)<br /><br /><br />      40:         /// andlt;/summaryandgt;<br /><br /><br />      41:         void Setup();<br /><br /><br />      42: <br /><br /><br />      43:         #endregion<br /><br /><br />      44: <br /><br /><br />      45:         #region Properties<br /><br /><br />      46: <br /><br /><br />      47:         MappingManager Manager { get; set; }<br /><br /><br />      48: <br /><br /><br />      49:         #endregion<br /><br /><br />      50:     }<br /><br /><br />      51: }<br /><br /><br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      28: #endregion<br /><br /><br />      29: <br /><br /><br />      30: namespace Utilities.IoC.Mappings.BaseClasses<br /><br /><br />      31: {<br /><br /><br />      32:     /// andlt;summaryandgt;<br /><br /><br />      33:     /// Base module class<br /><br /><br />      34:     /// andlt;/summaryandgt;<br /><br /><br />      35:     public abstract class BaseModule : IModule<br /><br /><br />      36:     {<br /><br /><br />      37:         #region Functions<br /><br /><br />      38: <br /><br /><br />      39:         public abstract void Setup();<br /><br /><br />      40: <br /><br /><br />      41:         /// andlt;summaryandgt;<br /><br /><br />      42:         /// Creates a mapping using a specific service type<br /><br /><br />      43:         /// andlt;/summaryandgt;<br /><br /><br />      44:         /// andlt;typeparam name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/typeparamandgt;<br /><br /><br />      45:         /// andlt;returnsandgt;A mapping objectandlt;/returnsandgt;<br /><br /><br />      46:         public virtual IMapping Mapandlt;ServiceTypeandgt;()<br /><br /><br />      47:         {<br /><br /><br />      48:             return Map(typeof(ServiceType));<br /><br /><br />      49:         }<br /><br /><br />      50: <br /><br /><br />      51:         /// andlt;summaryandgt;<br /><br /><br />      52:         /// Creates a mapping using a specific service type and attribute type<br /><br /><br />      53:         /// andlt;/summaryandgt;<br /><br /><br />      54:         /// andlt;typeparam name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/typeparamandgt;<br /><br /><br />      55:         /// andlt;typeparam name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/typeparamandgt;<br /><br /><br />      56:         /// andlt;returnsandgt;A mapping objectandlt;/returnsandgt;<br /><br /><br />      57:         public virtual IMapping Mapandlt;ServiceType, AttributeTypeandgt;()<br /><br /><br />      58:         {<br /><br /><br />      59:             return Map(typeof(ServiceType), typeof(AttributeType));<br /><br /><br />      60:         }<br /><br /><br />      61: <br /><br /><br />      62:         /// andlt;summaryandgt;<br /><br /><br />      63:         /// Creates a mapping using a specific service type<br /><br /><br />      64:         /// andlt;/summaryandgt;<br /><br /><br />      65:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      66:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />      67:         /// andlt;returnsandgt;A mapping objectandlt;/returnsandgt;<br /><br /><br />      68:         public virtual IMapping Map(Type ServiceType, Type AttributeType = null)<br /><br /><br />      69:         {<br /><br /><br />      70:             return Manager.CreateMapping(ServiceType, AttributeType);<br /><br /><br />      71:         }<br /><br /><br />      72: <br /><br /><br />      73:         #endregion<br /><br /><br />      74: <br /><br /><br />      75:         #region Properties<br /><br /><br />      76: <br /><br /><br />      77:         public virtual MappingManager Manager { get; set; }<br /><br /><br />      78: <br /><br /><br />      79:         #endregion<br /><br /><br />      80:     }<br /><br /><br />      81: }<br /><br /><br /><br />For example, in your code, you would define a module like this:<br /><br /><br />  <br />       1: public class Module : BaseModule<br /><br /><br />       2: {<br /><br /><br />       3:     public override void Setup()<br /><br /><br />       4:     {<br /><br /><br />       5:         Mapandlt;ITestInterfaceandgt;().Toandlt;TestClass1andgt;().SetScope(new StandardScope());<br /><br /><br />       6:         Mapandlt;TestClass1andgt;().Toandlt;TestClass1andgt;(() =andgt; new TestClass1());<br /><br /><br />       7:         Mapandlt;ITestInterface, MyAttributeandgt;().To(new TestImplementation());<br /><br /><br />       8:         Mapandlt;TestClass2andgt;().Toandlt;TestClass2andgt;();<br /><br /><br />       9:     }<br /><br /><br />      10: }<br /><br /><br /><br />This module defines four mappings that the system can use. A mapping is, as the name suggests, a mapping between a key type and what should be created when it encounters that type. For instance whenever I hit the interface ITestInterface, we return a TestClass1 object. The module can also define the scope for the object and sets the implementation used. In the example above the first item maps ITestInterface to TestClass1 and sets the scope to StandardScope. The third item maps ITestInterface items that have the MyAttribute attribute to the TestImplementation implementation. Whenever you call Map in a module, it creates and returns a Mapping class:<br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.BaseClasses;<br /><br /><br />      28: using Utilities.IoC.Providers;<br /><br /><br />      29: #endregion<br /><br /><br />      30: <br /><br /><br />      31: namespace Utilities.IoC.Mappings.Internal_Classes<br /><br /><br />      32: {<br /><br /><br />      33:     /// andlt;summaryandgt;<br /><br /><br />      34:     /// Mapping class<br /><br /><br />      35:     /// andlt;/summaryandgt;<br /><br /><br />      36:     public class Mapping : MappingKey<br /><br /><br />      37:     {<br /><br /><br />      38:         #region Constructors<br /><br /><br />      39: <br /><br /><br />      40:         /// andlt;summaryandgt;<br /><br /><br />      41:         /// Constructor<br /><br /><br />      42:         /// andlt;/summaryandgt;<br /><br /><br />      43:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      44:         public Mapping(Type ServiceType, ProviderManager ProviderManager, MappingManager MappingManager)<br /><br /><br />      45:             : base(ServiceType, null, ProviderManager, MappingManager)<br /><br /><br />      46:         {<br /><br /><br />      47:         }<br /><br /><br />      48: <br /><br /><br />      49:         /// andlt;summaryandgt;<br /><br /><br />      50:         /// Constructor<br /><br /><br />      51:         /// andlt;/summaryandgt;<br /><br /><br />      52:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      53:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />      54:         public Mapping(Type ServiceType, Type AttributeType, ProviderManager ProviderManager, MappingManager MappingManager)<br /><br /><br />      55:             : base(ServiceType, AttributeType, ProviderManager, MappingManager)<br /><br /><br />      56:         {<br /><br /><br />      57:         }<br /><br /><br />      58: <br /><br /><br />      59:         #endregion<br /><br /><br />      60:     }<br /><br /><br />      61: }<br /><br /><br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      28: using Utilities.IoC.Providers;<br /><br /><br />      29: #endregion<br /><br /><br />      30: <br /><br /><br />      31: namespace Utilities.IoC.Mappings.BaseClasses<br /><br /><br />      32: {<br /><br /><br />      33:     /// andlt;summaryandgt;<br /><br /><br />      34:     /// Mapping key<br /><br /><br />      35:     /// andlt;/summaryandgt;<br /><br /><br />      36:     public class MappingKey : BaseMapping<br /><br /><br />      37:     {<br /><br /><br />      38:         #region Constructor<br /><br /><br />      39: <br /><br /><br />      40:         public MappingKey(Type ServiceType, Type AttributeType, ProviderManager ProviderManager, MappingManager MappingManager)<br /><br /><br />      41:             : base(ServiceType, AttributeType, ProviderManager, MappingManager)<br /><br /><br />      42:         {<br /><br /><br />      43:         }<br /><br /><br />      44: <br /><br /><br />      45:         #endregion<br /><br /><br />      46: <br /><br /><br />      47:         #region Functions<br /><br /><br />      48: <br /><br /><br />      49:         public override bool Equals(object obj)<br /><br /><br />      50:         {<br /><br /><br />      51:             if (!(obj is IMapping))<br /><br /><br />      52:                 return false;<br /><br /><br />      53:             IMapping ObjectMapping = (IMapping)obj;<br /><br /><br />      54:             return ObjectMapping.AttributeType == AttributeType<br /><br /><br />      55:                 andamp;andamp; ObjectMapping.ServiceType == ServiceType;<br /><br /><br />      56:         }<br /><br /><br />      57: <br /><br /><br />      58:         public override int GetHashCode()<br /><br /><br />      59:         {<br /><br /><br />      60:             int AttributeHash = AttributeType == null ? 1 : AttributeType.GetHashCode();<br /><br /><br />      61:             int ServiceHash = ServiceType == null ? 1 : ServiceType.GetHashCode();<br /><br /><br />      62:             return ServiceHash * AttributeHash;<br /><br /><br />      63:         }<br /><br /><br />      64: <br /><br /><br />      65:         #endregion<br /><br /><br />      66:     }<br /><br /><br />      67: }<br /><br /><br /><br /><br />  <br />       1: /*<br /><br /><br />       2: Copyright (c) 2011 andlt;a href=andquot;http://www.gutgames.comandquot;andgt;James Craigandlt;/aandgt;<br /><br /><br />       3: <br /><br /><br />       4: Permission is hereby granted, free of charge, to any person obtaining a copy<br /><br /><br />       5: of this software and associated documentation files (the andquot;Softwareandquot;), to deal<br /><br /><br />       6: in the Software without restriction, including without limitation the rights<br /><br /><br />       7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br /><br /><br />       8: copies of the Software, and to permit persons to whom the Software is<br /><br /><br />       9: furnished to do so, subject to the following conditions:<br /><br /><br />      10: <br /><br /><br />      11: The above copyright notice and this permission notice shall be included in<br /><br /><br />      12: all copies or substantial portions of the Software.<br /><br /><br />      13: <br /><br /><br />      14: THE SOFTWARE IS PROVIDED andquot;AS ISandquot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br /><br /><br />      15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br /><br /><br />      16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br /><br /><br />      17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br /><br /><br />      18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br /><br /><br />      19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /><br /><br />      20: THE SOFTWARE.*/<br /><br /><br />      21: <br /><br /><br />      22: #region Usings<br /><br /><br />      23: using System;<br /><br /><br />      24: using System.Collections.Generic;<br /><br /><br />      25: using System.Linq;<br /><br /><br />      26: using System.Text;<br /><br /><br />      27: using Utilities.IoC.Mappings.Interfaces;<br /><br /><br />      28: using Utilities.IoC.Providers;<br /><br /><br />      29: using Utilities.IoC.Providers.Scope;<br /><br /><br />      30: using Utilities.IoC.Providers.Interfaces;<br /><br /><br />      31: #endregion<br /><br /><br />      32: <br /><br /><br />      33: namespace Utilities.IoC.Mappings.BaseClasses<br /><br /><br />      34: {<br /><br /><br />      35:     /// andlt;summaryandgt;<br /><br /><br />      36:     /// Base mapping<br /><br /><br />      37:     /// andlt;/summaryandgt;<br /><br /><br />      38:     public class BaseMapping : IMapping<br /><br /><br />      39:     {<br /><br /><br />      40:         #region Constructor<br /><br /><br />      41: <br /><br /><br />      42:         /// andlt;summaryandgt;<br /><br /><br />      43:         /// Constructor<br /><br /><br />      44:         /// andlt;/summaryandgt;<br /><br /><br />      45:         /// andlt;param name=andquot;ServiceTypeandquot;andgt;Service typeandlt;/paramandgt;<br /><br /><br />      46:         /// andlt;param name=andquot;AttributeTypeandquot;andgt;Attribute typeandlt;/paramandgt;<br /><br /><br />      47:         public BaseMapping(Type ServiceType, Type AttributeType, ProviderManager ProviderManager, MappingManager MappingManager)<br /><br /><br />      48:         {<br /><br /><br />      49:             this.ServiceType = ServiceType;<br /><br /><br />      50:             this.AttributeType = AttributeType;<br /><br /><br />      51:             this.ProviderManager = ProviderManager;<br /><br /><br />      52:             this.MappingManager = MappingManager;<br /><br /><br />      53:             this.Scope = new StandardScope();<br /><br /><br />      54:         }<br /><br /><br />      55: <br /><br /><br />      56:         #endregion<br /><br /><br />      57: <br /><br /><br />      58:         #region Functions<br /><br /><br />      59: <br /><br /><br />      60:         public virtual IMapping Toandlt;ImplementationTypeandgt;()<br /><br /><br />      61:         {<br /><br /><br />      62:             return To(typeof(ImplementationType));<br /><br /><br />      63:         }<br /><br /><br />      64: <br /><br /><br />      65:         public virtual IMapping To(Type ImplementationType)<br /><br /><br />      66:         {<br /><br /><br />      67:             Implementation = ProviderManager.GetProvider(Scope).CreateImplementation(ImplementationType, MappingManager);<br /><br /><br />      68:             return this;<br /><br /><br />      69:         }<br /><br /><br />      70: <br /><br /><br />      71:         public virtual IMapping Toandlt;ImplementationTypeandgt;(Funcandlt;ImplementationTypeandgt; Implementation)<br /><br /><br />      72:         {<br /><br /><br />      73:             this.Implementation = ProviderManager.GetProvider(Scope).CreateImplementation(Implementation);<br /><br /><br />      74:             return this;<br /><br /><br />      75:         }<br /><br /><br />      76: <br /><br /><br />      77:         public virtual IMapping To(Providers.Interfaces.IImplementation Implementation)<br /><br /><br />      78:         {<br /><br /><br />      79:             this.Implementation = Implementation;<br /><br /><br />      80:             return this;<br /><br /><br />      81:         }<br /><br /><br />      82: <br /><br /><br />      83:         public virtual IMapping SetScope(BaseScope Scope)<br /><br /><br />      84:         {<br /><br /><br />      85:             this.Scope = Scope;<br /><br /><br />      86:             Implementation = ProviderManager.GetProvider(Scope).CreateImplementation(Implementation, MappingManager);<br /><br /><br />      87:             return this;<br /><br /><br />      88:         }<br /><br /><br />      89: <br /><br /><br />      90:         #endregion<br /><br /><br />      91: <br /><br /><br />      92:         #region Properties<br /><br /><br />      93: <br /><br /><br />      94:         public virtual Type ServiceType { get; protected set; }<br /><br /><br />      95:         public virtual Type AttributeType { get; protected set; }<br /><br /><br />      96:         public virtual BaseScope Scope { get; protected set; }<br /><br /><br />      97:         public virtual IImplementation Implementation { get; protected set; }<br /><br /><br />      98:         protected virtual ProviderManager ProviderManager { get; set; }<br /><br /><br />      99:         protected virtual MappingManager MappingManager { get; set; }<br /><br /><br />     100: <br /><br /><br />     101:         #endregion<br /><br /><br />     102:     }<br /><br /><br />     103: }<br /><br /><br /><br />The Mapping class is rather empty, the MappingKey actually defines the functions needed to determine which mapping is which. And the BaseMapping class holds the functions that set the scope, set the implementation, etc. And with that we’re done.<br /><br />We create our modules, which sets our mappings, which the system holds for us until we tell the manager to get us a specific object type. Once we do that, it assembles our object for us. It’s not that complicated really and not that much code either (the largest file tops out at 189 lines of code including comments). And with that we have ourselves a simple DI container.<br /><br />If you want updates, or find bugs, etc. check out the repository for the utility library (this is currently under the Utilities.IoC namespace). I’m terrible about updating my site but I update the code there whenever a bug is found. And hopefully I’ll finish my huge update to that library before too long (and it is going to contain a number of changes and additions). Anyway, take a look at the code and happy coding.]]></itunes:summary></item>
<item><title>Utility Library Progress</title>
<link>http://www.gutgames.com/post/Utility-Library-Progress.aspx</link>
<author>James Craig</author>
<pubDate>Thu, 08 Sep 2011 21:38:08 GMT</pubDate>
<description><![CDATA[Between losing power for a week, being without internet for another week, and having family in town for yet another week, I’ve had no chance to post this. Nor have I had a chance to post a number of things that I’ve been meaning to. Hopefully that will change here. So if you've been following my utility library's progress, you'll know that I'm doing a major rework of a number of classes, I've been going in and rewriting my private unit tests so I can actually release them to everyone, and I've been clearing out old code that I no longer use or plan to maintain. This means that if you plan on going from the current 2.2 to what will become 3.0, you'll need to make some changes to your code.  For example, let's look at some encryption code. Before if you wanted to encrypt something you would have to call the static function Utilities.Encryption.AESEncryption.Encrypt. It only took in a string and would only encrypt it using AES:             1: /// andlt;summaryandgt;<br /><br /><br />       2: /// Encrypts a string<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: /// andlt;param name=andquot;PlainTextandquot;andgt;Text to be encryptedandlt;/paramandgt;<br /><br /><br />       5: /// andlt;param name=andquot;Passwordandquot;andgt;Password to encrypt withandlt;/paramandgt;<br /><br /><br />       6: /// andlt;param name=andquot;Saltandquot;andgt;Salt to encrypt withandlt;/paramandgt;<br /><br /><br />       7: /// andlt;param name=andquot;HashAlgorithmandquot;andgt;Can be either SHA1 or MD5andlt;/paramandgt;<br /><br /><br />       8: /// andlt;param name=andquot;PasswordIterationsandquot;andgt;Number of iterations to doandlt;/paramandgt;<br /><br /><br />       9: /// andlt;param name=andquot;InitialVectorandquot;andgt;Needs to be 16 ASCII characters longandlt;/paramandgt;<br /><br /><br />      10: /// andlt;param name=andquot;KeySizeandquot;andgt;Can be 128, 192, or 256andlt;/paramandgt;<br /><br /><br />      11: /// andlt;returnsandgt;An encrypted stringandlt;/returnsandgt;<br /><br /><br />      12: public static string Encrypt(string PlainText, string Password,<br /><br /><br />      13:     string Salt = andquot;Kosherandquot;, string HashAlgorithm = andquot;SHA1andquot;,<br /><br /><br />      14:     int PasswordIterations = 2, string InitialVector = andquot;OFRna73m*aze01xYandquot;,<br /><br /><br />      15:     int KeySize = 256)<br /><br /><br />      16: {<br /><br /><br />      17:     if (string.IsNullOrEmpty(PlainText))<br /><br /><br />      18:         return andquot;andquot;;<br /><br /><br />      19:     if (string.IsNullOrEmpty(Password))<br /><br /><br />      20:         throw new ArgumentNullException(andquot;Passwordandquot;);<br /><br /><br />      21:     if(string.IsNullOrEmpty(Salt))<br /><br /><br />      22:         throw new ArgumentNullException(andquot;Saltandquot;);<br /><br /><br />      23:     if(string.IsNullOrEmpty(HashAlgorithm))<br /><br /><br />      24:         throw new ArgumentNullException(andquot;HashAlgorithmandquot;);<br /><br /><br />      25:     if (string.IsNullOrEmpty(InitialVector))<br /><br /><br />      26:         throw new ArgumentNullException(andquot;InitialVectorandquot;);<br /><br /><br />      27:     byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);<br /><br /><br />      28:     byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);<br /><br /><br />      29:     byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText);<br /><br /><br />      30:     PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);<br /><br /><br />      31:     byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);<br /><br /><br />      32:     RijndaelManaged SymmetricKey = new RijndaelManaged();<br /><br /><br />      33:     SymmetricKey.Mode = CipherMode.CBC;<br /><br /><br />      34:     byte[] CipherTextBytes = null;<br /><br /><br />      35:     using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes))<br /><br /><br />      36:     {<br /><br /><br />      37:         using (MemoryStream MemStream = new MemoryStream())<br /><br /><br />      38:         {<br /><br /><br />      39:             using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))<br /><br /><br />      40:             {<br /><br /><br />      41:                 CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);<br /><br /><br />      42:                 CryptoStream.FlushFinalBlock();<br /><br /><br />      43:                 CipherTextBytes = MemStream.ToArray();<br /><br /><br />      44:                 MemStream.Close();<br /><br /><br />      45:                 CryptoStream.Close();<br /><br /><br />      46:             }<br /><br /><br />      47:         }<br /><br /><br />      48:     }<br /><br /><br />      49:     SymmetricKey.Clear();<br /><br /><br />      50:     return Convert.ToBase64String(CipherTextBytes);<br /><br /><br />      51: }<br /><br /><br /><br />In fact you had to use different static functions to use other encryption standards (DES, TripleDES, etc). And each of those functions took in different parameters:<br /><br />DES:<br /><br /><br />  <br />       1: public static string Encrypt(string Input, string Key)<br /><br /><br /><br />vs AES:<br /><br /><br />  <br />       1: public static string Encrypt(string PlainText, string Password,<br /><br /><br />       2:             string Salt = andquot;Kosherandquot;, string HashAlgorithm = andquot;SHA1andquot;,<br /><br /><br />       3:             int PasswordIterations = 2, string InitialVector = andquot;OFRna73m*aze01xYandquot;,<br /><br /><br />       4:             int KeySize = 256)<br /><br /><br /><br />With the newer code though things are different. Instead you can encrypt a string doing this:<br /><br /><br />  <br />       1: string Data = andquot;This is a test of the system.andquot;;<br /><br /><br />       2: Data=Data.Encrypt(andquot;Babysfirstkeyandquot;);<br /><br /><br /><br />Using this function:<br /><br /><br />  <br />       1: /// andlt;summaryandgt;<br /><br /><br />       2: /// Encrypts a string<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: /// andlt;param name=andquot;Dataandquot;andgt;Text to be encryptedandlt;/paramandgt;<br /><br /><br />       5: /// andlt;param name=andquot;Keyandquot;andgt;Password to encrypt withandlt;/paramandgt;<br /><br /><br />       6: /// andlt;param name=andquot;AlgorithmUsingandquot;andgt;Algorithm to use for encryption (defaults to AES)andlt;/paramandgt;<br /><br /><br />       7: /// andlt;param name=andquot;Saltandquot;andgt;Salt to encrypt withandlt;/paramandgt;<br /><br /><br />       8: /// andlt;param name=andquot;HashAlgorithmandquot;andgt;Can be either SHA1 or MD5andlt;/paramandgt;<br /><br /><br />       9: /// andlt;param name=andquot;PasswordIterationsandquot;andgt;Number of iterations to doandlt;/paramandgt;<br /><br /><br />      10: /// andlt;param name=andquot;InitialVectorandquot;andgt;Needs to be 16 ASCII characters longandlt;/paramandgt;<br /><br /><br />      11: /// andlt;param name=andquot;KeySizeandquot;andgt;Can be 64 (DES only), 128 (AES), 192 (AES and Triple DES), or 256 (AES)andlt;/paramandgt;<br /><br /><br />      12: /// andlt;param name=andquot;EncodingUsingandquot;andgt;Encoding that the original string is using (defaults to UTF8)andlt;/paramandgt;<br /><br /><br />      13: /// andlt;returnsandgt;An encrypted string (Base 64 string)andlt;/returnsandgt;<br /><br /><br />      14: public static string Encrypt(this string Data, string Key,<br /><br /><br />      15:     Encoding EncodingUsing = null,<br /><br /><br />      16:     SymmetricAlgorithm AlgorithmUsing = null, string Salt = andquot;Kosherandquot;,<br /><br /><br />      17:     string HashAlgorithm = andquot;SHA1andquot;, int PasswordIterations = 2,<br /><br /><br />      18:     string InitialVector = andquot;OFRna73m*aze01xYandquot;, int KeySize = 256)<br /><br /><br />      19: {<br /><br /><br />      20:     if (string.IsNullOrEmpty(Data))<br /><br /><br />      21:         return andquot;andquot;;<br /><br /><br />      22:     return Data.ToByteArray(EncodingUsing).Encrypt(Key, AlgorithmUsing, Salt, HashAlgorithm, PasswordIterations, InitialVector, KeySize).ToBase64String();<br /><br /><br />      23: }<br /><br /><br />      24: <br /><br /><br />      25: /// andlt;summaryandgt;<br /><br /><br />      26: /// Encrypts a byte array<br /><br /><br />      27: /// andlt;/summaryandgt;<br /><br /><br />      28: /// andlt;param name=andquot;Dataandquot;andgt;Data to be encryptedandlt;/paramandgt;<br /><br /><br />      29: /// andlt;param name=andquot;Keyandquot;andgt;Password to encrypt withandlt;/paramandgt;<br /><br /><br />      30: /// andlt;param name=andquot;AlgorithmUsingandquot;andgt;Algorithm to use for encryption (defaults to AES)andlt;/paramandgt;<br /><br /><br />      31: /// andlt;param name=andquot;Saltandquot;andgt;Salt to encrypt withandlt;/paramandgt;<br /><br /><br />      32: /// andlt;param name=andquot;HashAlgorithmandquot;andgt;Can be either SHA1 or MD5andlt;/paramandgt;<br /><br /><br />      33: /// andlt;param name=andquot;PasswordIterationsandquot;andgt;Number of iterations to doandlt;/paramandgt;<br /><br /><br />      34: /// andlt;param name=andquot;InitialVectorandquot;andgt;Needs to be 16 ASCII characters longandlt;/paramandgt;<br /><br /><br />      35: /// andlt;param name=andquot;KeySizeandquot;andgt;Can be 64 (DES only), 128 (AES), 192 (AES and Triple DES), or 256 (AES)andlt;/paramandgt;<br /><br /><br />      36: /// andlt;returnsandgt;An encrypted byte arrayandlt;/returnsandgt;<br /><br /><br />      37: public static byte[] Encrypt(this byte[] Data, string Key,<br /><br /><br />      38:     SymmetricAlgorithm AlgorithmUsing = null, string Salt = andquot;Kosherandquot;,<br /><br /><br />      39:     string HashAlgorithm = andquot;SHA1andquot;, int PasswordIterations = 2,<br /><br /><br />      40:     string InitialVector = andquot;OFRna73m*aze01xYandquot;, int KeySize = 256)<br /><br /><br />      41: {<br /><br /><br />      42:     if (Data == null)<br /><br /><br />      43:         return null;<br /><br /><br />      44:     if (AlgorithmUsing == null)<br /><br /><br />      45:         AlgorithmUsing = new RijndaelManaged();<br /><br /><br />      46:     if (string.IsNullOrEmpty(Key))<br /><br /><br />      47:         throw new ArgumentNullException(andquot;Keyandquot;);<br /><br /><br />      48:     if (string.IsNullOrEmpty(Salt))<br /><br /><br />      49:         throw new ArgumentNullException(andquot;Saltandquot;);<br /><br /><br />      50:     if (string.IsNullOrEmpty(HashAlgorithm))<br /><br /><br />      51:         throw new ArgumentNullException(andquot;HashAlgorithmandquot;);<br /><br /><br />      52:     if (string.IsNullOrEmpty(InitialVector))<br /><br /><br />      53:         throw new ArgumentNullException(andquot;InitialVectorandquot;);<br /><br /><br />      54:     using (PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Key, Salt.ToByteArray(), HashAlgorithm, PasswordIterations))<br /><br /><br />      55:     {<br /><br /><br />      56:         using (SymmetricAlgorithm SymmetricKey = AlgorithmUsing)<br /><br /><br />      57:         {<br /><br /><br />      58:             SymmetricKey.Mode = CipherMode.CBC;<br /><br /><br />      59:             byte[] CipherTextBytes = null;<br /><br /><br />      60:             using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(DerivedPassword.GetBytes(KeySize / 8), InitialVector.ToByteArray()))<br /><br /><br />      61:             {<br /><br /><br />      62:                 using (MemoryStream MemStream = new MemoryStream())<br /><br /><br />      63:                 {<br /><br /><br />      64:                     using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))<br /><br /><br />      65:                     {<br /><br /><br />      66:                         CryptoStream.Write(Data, 0, Data.Length);<br /><br /><br />      67:                         CryptoStream.FlushFinalBlock();<br /><br /><br />      68:                         CipherTextBytes = MemStream.ToArray();<br /><br /><br />      69:                         MemStream.Close();<br /><br /><br />      70:                         CryptoStream.Close();<br /><br /><br />      71:                     }<br /><br /><br />      72:                 }<br /><br /><br />      73:             }<br /><br /><br />      74:             SymmetricKey.Clear();<br /><br /><br />      75:             return CipherTextBytes;<br /><br /><br />      76:         }<br /><br /><br />      77:     }<br /><br /><br />      78: }<br /><br /><br /><br />Well, in reality 2 functions, plus there are a number of calls to other extension methods that I’ve added called through out. Anyway, with the newer code most of the static functions have been moved to being extension methods (where it makes sense anyway). On top of that many of the functions now work on multiple data types (the encryption functions now work on strings and byte arrays for example). I've also tried to give decent default values for everything (when I can) and tried to make things a bit more generic. For instance the one encryption method above does AES, DES, and TripleDES (along with RC2 and any other class that inherits from SymmetricAlgorithm). All you do is pass in the algorithm class you want to use and it handles the rest (and if you don't pass in anything it defaults to AES). This should make using the code much simpler and more succinct than it was in the past.<br /><br />The same thing is going on for a number of classes (FileManager is now a series of extensions for the FileInfo and DirectoryInfo classes, Serialization class is now extension methods added onto byte arrays, XmlDocuments, etc). And in each of these instances I'm trying to reduce the amount of code that you will need to write. At least for me it's easier to write:<br /><br /><br />  <br />       1: TestClass TestItem=new TestClass();<br /><br /><br />       2: TestItem.ToXML(@andquot;.\Testing\Test.xmlandquot;);<br /><br /><br /><br />than<br /><br /><br />  <br />       1: TestClass TestObject=new TestClass();<br /><br /><br />       2: Utilities.IO.Serialization.ObjectToXML(TestObject,@andquot;.\Testing\Test.xmlandquot;);<br /><br /><br /><br />Plus it gives it a nicer fluent interface feel which is easier to follow as I try to make sure that everything returns some value that you can act on. Anyway, if you're at all interested in influencing the direction that I go with this then drop into the CodePlex site and let me know your opinion in the discussions section and next time I'll be starting a series on building a Dependency Injection library.]]></description>
<itunes:subtitle>Utility Library Progress</itunes:subtitle><itunes:summary><![CDATA[Between losing power for a week, being without internet for another week, and having family in town for yet another week, I’ve had no chance to post this. Nor have I had a chance to post a number of things that I’ve been meaning to. Hopefully that will change here. So if you've been following my utility library's progress, you'll know that I'm doing a major rework of a number of classes, I've been going in and rewriting my private unit tests so I can actually release them to everyone, and I've been clearing out old code that I no longer use or plan to maintain. This means that if you plan on going from the current 2.2 to what will become 3.0, you'll need to make some changes to your code.  For example, let's look at some encryption code. Before if you wanted to encrypt something you would have to call the static function Utilities.Encryption.AESEncryption.Encrypt. It only took in a string and would only encrypt it using AES:             1: /// andlt;summaryandgt;<br /><br /><br />       2: /// Encrypts a string<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: /// andlt;param name=andquot;PlainTextandquot;andgt;Text to be encryptedandlt;/paramandgt;<br /><br /><br />       5: /// andlt;param name=andquot;Passwordandquot;andgt;Password to encrypt withandlt;/paramandgt;<br /><br /><br />       6: /// andlt;param name=andquot;Saltandquot;andgt;Salt to encrypt withandlt;/paramandgt;<br /><br /><br />       7: /// andlt;param name=andquot;HashAlgorithmandquot;andgt;Can be either SHA1 or MD5andlt;/paramandgt;<br /><br /><br />       8: /// andlt;param name=andquot;PasswordIterationsandquot;andgt;Number of iterations to doandlt;/paramandgt;<br /><br /><br />       9: /// andlt;param name=andquot;InitialVectorandquot;andgt;Needs to be 16 ASCII characters longandlt;/paramandgt;<br /><br /><br />      10: /// andlt;param name=andquot;KeySizeandquot;andgt;Can be 128, 192, or 256andlt;/paramandgt;<br /><br /><br />      11: /// andlt;returnsandgt;An encrypted stringandlt;/returnsandgt;<br /><br /><br />      12: public static string Encrypt(string PlainText, string Password,<br /><br /><br />      13:     string Salt = andquot;Kosherandquot;, string HashAlgorithm = andquot;SHA1andquot;,<br /><br /><br />      14:     int PasswordIterations = 2, string InitialVector = andquot;OFRna73m*aze01xYandquot;,<br /><br /><br />      15:     int KeySize = 256)<br /><br /><br />      16: {<br /><br /><br />      17:     if (string.IsNullOrEmpty(PlainText))<br /><br /><br />      18:         return andquot;andquot;;<br /><br /><br />      19:     if (string.IsNullOrEmpty(Password))<br /><br /><br />      20:         throw new ArgumentNullException(andquot;Passwordandquot;);<br /><br /><br />      21:     if(string.IsNullOrEmpty(Salt))<br /><br /><br />      22:         throw new ArgumentNullException(andquot;Saltandquot;);<br /><br /><br />      23:     if(string.IsNullOrEmpty(HashAlgorithm))<br /><br /><br />      24:         throw new ArgumentNullException(andquot;HashAlgorithmandquot;);<br /><br /><br />      25:     if (string.IsNullOrEmpty(InitialVector))<br /><br /><br />      26:         throw new ArgumentNullException(andquot;InitialVectorandquot;);<br /><br /><br />      27:     byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);<br /><br /><br />      28:     byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);<br /><br /><br />      29:     byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText);<br /><br /><br />      30:     PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);<br /><br /><br />      31:     byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);<br /><br /><br />      32:     RijndaelManaged SymmetricKey = new RijndaelManaged();<br /><br /><br />      33:     SymmetricKey.Mode = CipherMode.CBC;<br /><br /><br />      34:     byte[] CipherTextBytes = null;<br /><br /><br />      35:     using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes))<br /><br /><br />      36:     {<br /><br /><br />      37:         using (MemoryStream MemStream = new MemoryStream())<br /><br /><br />      38:         {<br /><br /><br />      39:             using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))<br /><br /><br />      40:             {<br /><br /><br />      41:                 CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);<br /><br /><br />      42:                 CryptoStream.FlushFinalBlock();<br /><br /><br />      43:                 CipherTextBytes = MemStream.ToArray();<br /><br /><br />      44:                 MemStream.Close();<br /><br /><br />      45:                 CryptoStream.Close();<br /><br /><br />      46:             }<br /><br /><br />      47:         }<br /><br /><br />      48:     }<br /><br /><br />      49:     SymmetricKey.Clear();<br /><br /><br />      50:     return Convert.ToBase64String(CipherTextBytes);<br /><br /><br />      51: }<br /><br /><br /><br />In fact you had to use different static functions to use other encryption standards (DES, TripleDES, etc). And each of those functions took in different parameters:<br /><br />DES:<br /><br /><br />  <br />       1: public static string Encrypt(string Input, string Key)<br /><br /><br /><br />vs AES:<br /><br /><br />  <br />       1: public static string Encrypt(string PlainText, string Password,<br /><br /><br />       2:             string Salt = andquot;Kosherandquot;, string HashAlgorithm = andquot;SHA1andquot;,<br /><br /><br />       3:             int PasswordIterations = 2, string InitialVector = andquot;OFRna73m*aze01xYandquot;,<br /><br /><br />       4:             int KeySize = 256)<br /><br /><br /><br />With the newer code though things are different. Instead you can encrypt a string doing this:<br /><br /><br />  <br />       1: string Data = andquot;This is a test of the system.andquot;;<br /><br /><br />       2: Data=Data.Encrypt(andquot;Babysfirstkeyandquot;);<br /><br /><br /><br />Using this function:<br /><br /><br />  <br />       1: /// andlt;summaryandgt;<br /><br /><br />       2: /// Encrypts a string<br /><br /><br />       3: /// andlt;/summaryandgt;<br /><br /><br />       4: /// andlt;param name=andquot;Dataandquot;andgt;Text to be encryptedandlt;/paramandgt;<br /><br /><br />       5: /// andlt;param name=andquot;Keyandquot;andgt;Password to encrypt withandlt;/paramandgt;<br /><br /><br />       6: /// andlt;param name=andquot;AlgorithmUsingandquot;andgt;Algorithm to use for encryption (defaults to AES)andlt;/paramandgt;<br /><br /><br />       7: /// andlt;param name=andquot;Saltandquot;andgt;Salt to encrypt withandlt;/paramandgt;<br /><br /><br />       8: /// andlt;param name=andquot;HashAlgorithmandquot;andgt;Can be either SHA1 or MD5andlt;/paramandgt;<br /><br /><br />       9: /// andlt;param name=andquot;PasswordIterationsandquot;andgt;Number of iterations to doandlt;/paramandgt;<br /><br /><br />      10: /// andlt;param name=andquot;InitialVectorandquot;andgt;Needs to be 16 ASCII characters longandlt;/paramandgt;<br /><br /><br />      11: /// andlt;param name=andquot;KeySizeandquot;andgt;Can be 64 (DES only), 128 (AES), 192 (AES and Triple DES), or 256 (AES)andlt;/paramandgt;<br /><br /><br />      12: /// andlt;param name=andquot;EncodingUsingandquot;andgt;Encoding that the original string is using (defaults to UTF8)andlt;/paramandgt;<br /><br /><br />      13: /// andlt;returnsandgt;An encrypted string (Base 64 string)andlt;/returnsandgt;<br /><br /><br />      14: public static string Encrypt(this string Data, string Key,<br /><br /><br />      15:     Encoding EncodingUsing = null,<br /><br /><br />      16:     SymmetricAlgorithm AlgorithmUsing = null, string Salt = andquot;Kosherandquot;,<br /><br /><br />      17:     string HashAlgorithm = andquot;SHA1andquot;, int PasswordIterations = 2,<br /><br /><br />      18:     string InitialVector = andquot;OFRna73m*aze01xYandquot;, int KeySize = 256)<br /><br /><br />      19: {<br /><br /><br />      20:     if (string.IsNullOrEmpty(Data))<br /><br /><br />      21:         return andquot;andquot;;<br /><br /><br />      22:     return Data.ToByteArray(EncodingUsing).Encrypt(Key, AlgorithmUsing, Salt, HashAlgorithm, PasswordIterations, InitialVector, KeySize).ToBase64String();<br /><br /><br />      23: }<br /><br /><br />      24: <br /><br /><br />      25: /// andlt;summaryandgt;<br /><br /><br />      26: /// Encrypts a byte array<br /><br /><br />      27: /// andlt;/summaryandgt;<br /><br /><br />      28: /// andlt;param name=andquot;Dataandquot;andgt;Data to be encryptedandlt;/paramandgt;<br /><br /><br />      29: /// andlt;param name=andquot;Keyandquot;andgt;Password to encrypt withandlt;/paramandgt;<br /><br /><br />      30: /// andlt;param name=andquot;AlgorithmUsingandquot;andgt;Algorithm to use for encryption (defaults to AES)andlt;/paramandgt;<br /><br /><br />      31: /// andlt;param name=andquot;Saltandquot;andgt;Salt to encrypt withandlt;/paramandgt;<br /><br /><br />      32: /// andlt;param name=andquot;HashAlgorithmandquot;andgt;Can be either SHA1 or MD5andlt;/paramandgt;<br /><br /><br />      33: /// andlt;param name=andquot;PasswordIterationsandquot;andgt;Number of iterations to doandlt;/paramandgt;<br /><br /><br />      34: /// andlt;param name=andquot;InitialVectorandquot;andgt;Needs to be 16 ASCII characters longandlt;/paramandgt;<br /><br /><br />      35: /// andlt;param name=andquot;KeySizeandquot;andgt;Can be 64 (DES only), 128 (AES), 192 (AES and Triple DES), or 256 (AES)andlt;/paramandgt;<br /><br /><br />      36: /// andlt;returnsandgt;An encrypted byte arrayandlt;/returnsandgt;<br /><br /><br />      37: public static byte[] Encrypt(this byte[] Data, string Key,<br /><br /><br />      38:     SymmetricAlgorithm AlgorithmUsing = null, string Salt = andquot;Kosherandquot;,<br /><br /><br />      39:     string HashAlgorithm = andquot;SHA1andquot;, int PasswordIterations = 2,<br /><br /><br />      40:     string InitialVector = andquot;OFRna73m*aze01xYandquot;, int KeySize = 256)<br /><br /><br />      41: {<br /><br /><br />      42:     if (Data == null)<br /><br /><br />      43:         return null;<br /><br /><br />      44:     if (AlgorithmUsing == null)<br /><br /><br />      45:         AlgorithmUsing = new RijndaelManaged();<br /><br /><br />      46:     if (string.IsNullOrEmpty(Key))<br /><br /><br />      47:         throw new ArgumentNullException(andquot;Keyandquot;);<br /><br /><br />      48:     if (string.IsNullOrEmpty(Salt))<br /><br /><br />      49:         throw new ArgumentNullException(andquot;Saltandquot;);<br /><br /><br />      50:     if (string.IsNullOrEmpty(HashAlgorithm))<br /><br /><br />      51:         throw new ArgumentNullException(andquot;HashAlgorithmandquot;);<br /><br /><br />      52:     if (string.IsNullOrEmpty(InitialVector))<br /><br /><br />      53:         throw new ArgumentNullException(andquot;InitialVectorandquot;);<br /><br /><br />      54:     using (PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Key, Salt.ToByteArray(), HashAlgorithm, PasswordIterations))<br /><br /><br />      55:     {<br /><br /><br />      56:         using (SymmetricAlgorithm SymmetricKey = AlgorithmUsing)<br /><br /><br />      57:         {<br /><br /><br />      58:             SymmetricKey.Mode = CipherMode.CBC;<br /><br /><br />      59:             byte[] CipherTextBytes = null;<br /><br /><br />      60:             using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(DerivedPassword.GetBytes(KeySize / 8), InitialVector.ToByteArray()))<br /><br /><br />      61:             {<br /><br /><br />      62:                 using (MemoryStream MemStream = new MemoryStream())<br /><br /><br />      63:                 {<br /><br /><br />      64:                     using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))<br /><br /><br />      65:                     {<br /><br /><br />      66:                         CryptoStream.Write(Data, 0, Data.Length);<br /><br /><br />      67:                         CryptoStream.FlushFinalBlock();<br /><br /><br />      68:                         CipherTextBytes = MemStream.ToArray();<br /><br /><br />      69:                         MemStream.Close();<br /><br /><br />      70:                         CryptoStream.Close();<br /><br /><br />      71:                     }<br /><br /><br />      72:                 }<br /><br /><br />      73:             }<br /><br /><br />      74:             SymmetricKey.Clear();<br /><br /><br />      75:             return CipherTextBytes;<br /><br /><br />      76:         }<br /><br /><br />      77:     }<br /><br /><br />      78: }<br /><br /><br /><br />Well, in reality 2 functions, plus there are a number of calls to other extension methods that I’ve added called through out. Anyway, with the newer code most of the static functions have been moved to being extension methods (where it makes sense anyway). On top of that many of the functions now work on multiple data types (the encryption functions now work on strings and byte arrays for example). I've also tried to give decent default values for everything (when I can) and tried to make things a bit more generic. For instance the one encryption method above does AES, DES, and TripleDES (along with RC2 and any other class that inherits from SymmetricAlgorithm). All you do is pass in the algorithm class you want to use and it handles the rest (and if you don't pass in anything it defaults to AES). This should make using the code much simpler and more succinct than it was in the past.<br /><br />The same thing is going on for a number of classes (FileManager is now a series of extensions for the FileInfo and DirectoryInfo classes, Serialization class is now extension methods added onto byte arrays, XmlDocuments, etc). And in each of these instances I'm trying to reduce the amount of code that you will need to write. At least for me it's easier to write:<br /><br /><br />  <br />       1: TestClass TestItem=new TestClass();<br /><br /><br />       2: TestItem.ToXML(@andquot;.\Testing\Test.xmlandquot;);<br /><br /><br /><br />than<br /><br /><br />  <br />       1: TestClass TestObject=new TestClass();<br /><br /><br />       2: Utilities.IO.Serialization.ObjectToXML(TestObject,@andquot;.\Testing\Test.xmlandquot;);<br /><br /><br /><br />Plus it gives it a nicer fluent interface feel which is easier to follow as I try to make sure that everything returns some value that you can act on. Anyway, if you're at all interested in influencing the direction that I go with this then drop into the CodePlex site and let me know your opinion in the discussions section and next time I'll be starting a series on building a Dependency Injection library.]]></itunes:summary></item>
<item><title>Why You Should Sign Your DLLs</title>
<link>http://www.gutgames.com/post/Why-You-Should-Sign-Your-DLLs.aspx</link>
<author>James Craig</author>
<pubDate>Sun, 07 Aug 2011 21:26:19 GMT</pubDate>
<description><![CDATA[Generally speaking I do not deal with security issues much. I mean I can set up SSL, set up a form based authentication, etc. the basic stuff. But one thing that I almost always do in my applications is sign the DLLs. The main reason I do this is because of a former coworker of mine.  You see, years ago I worked with a guy who liked to mess with people. He liked to put new hires through a “hazing” ritual. Specifically he had this application that he wrote that would analyze a DLL, find the class/functions that were available in the DLL, and generate some default classes with the same names (basically he generated stubs). He would do this with one of the third party DLLs that we were using, slip it onto your machine, and come over and tell you that whatever app you had just shipped wasn’t working correctly. You’d start up the app and nothing would work. It would start up fine, but everything from the one DLL would return null/default values.  The reason he was able to do this was because the way that DLLs are loaded is dumb. I don’t mean it’s done in a stupid way, well it is sort of. When you link to a DLL that is named MyDLLs.dll, it will load anything as long as it has the same name by default. As an example, let’s assume that I have an app called TestApp:             1: using System;<br /><br /><br />       2: using System.Collections.Generic;<br /><br /><br />       3: using System.Linq;<br /><br /><br />       4: using System.Text;<br /><br /><br />       5: using Utilities.DataTypes.Patterns;<br /><br /><br />       6: <br /><br /><br />       7: namespace TestApp<br /><br /><br />       8: {<br /><br /><br />       9:     class Program<br /><br /><br />      10:     {<br /><br /><br />      11:         static void Main(string[] args)<br /><br /><br />      12:         {<br /><br /><br />      13:             Factoryandlt;string, stringandgt; Factory = new Factoryandlt;string, stringandgt;();<br /><br /><br />      14:             Factory.Register(andquot;Aandquot;, andquot;Bandquot;);<br /><br /><br />      15:             Console.WriteLine(Factory.Create(andquot;Aandquot;));<br /><br /><br />      16:             Console.ReadLine();<br /><br /><br />      17:         }<br /><br /><br />      18:     }<br /><br /><br />      19: }<br /><br /><br /><br />It’s simple enough, all it’s doing is using the default System DLLs and one extra DLL called Utilities (and yes, it’s a class from my utility library but let’s assume that it’s not). The Utilities DLL has a class called Factory:<br /><br /><br />  <br />       1: using System;<br /><br /><br />       2: using System.Collections.Generic;<br /><br /><br />       3: using System.Linq;<br /><br /><br />       4: using System.Text;<br /><br /><br />       5: <br /><br /><br />       6: namespace Utilities.DataTypes.Patterns<br /><br /><br />       7: {<br /><br /><br />       8:     public class Factoryandlt;Key, Tandgt;<br /><br /><br />       9:     {<br /><br /><br />      10:         #region Constructors<br /><br /><br />      11: <br /><br /><br />      12:         /// andlt;summaryandgt;<br /><br /><br />      13:         /// Constructor<br /><br /><br />      14:         /// andlt;/summaryandgt;<br /><br /><br />      15:         public Factory()<br /><br /><br />      16:         {<br /><br /><br />      17:             Constructors = new Dictionaryandlt;Key, Funcandlt;Tandgt;andgt;();<br /><br /><br />      18:         }<br /><br /><br />      19: <br /><br /><br />      20:         #endregion<br /><br /><br />      21: <br /><br /><br />      22:         #region Protected Variables<br /><br /><br />      23: <br /><br /><br />      24:         /// andlt;summaryandgt;<br /><br /><br />      25:         /// List of constructors/initializers<br /><br /><br />      26:         /// andlt;/summaryandgt;<br /><br /><br />      27:         protected virtual Dictionaryandlt;Key, Funcandlt;Tandgt;andgt; Constructors { get; set; }<br /><br /><br />      28: <br /><br /><br />      29:         #endregion<br /><br /><br />      30: <br /><br /><br />      31:         #region Public Functions<br /><br /><br />      32: <br /><br /><br />      33:         /// andlt;summaryandgt;<br /><br /><br />      34:         /// Registers an item<br /><br /><br />      35:         /// andlt;/summaryandgt;<br /><br /><br />      36:         /// andlt;param name=andquot;Keyandquot;andgt;Item to registerandlt;/paramandgt;<br /><br /><br />      37:         /// andlt;param name=andquot;Resultandquot;andgt;The object to be returnedandlt;/paramandgt;<br /><br /><br />      38:         public virtual void Register(Key Key, T Result)<br /><br /><br />      39:         {<br /><br /><br />      40:             if (Exists(Key))<br /><br /><br />      41:                 Constructors[Key] = new Funcandlt;Tandgt;(() =andgt; Result);<br /><br /><br />      42:             else<br /><br /><br />      43:                 Constructors.Add(Key, new Funcandlt;Tandgt;(() =andgt; Result));<br /><br /><br />      44:         }<br /><br /><br />      45: <br /><br /><br />      46:         /// andlt;summaryandgt;<br /><br /><br />      47:         /// Registers an item<br /><br /><br />      48:         /// andlt;/summaryandgt;<br /><br /><br />      49:         /// andlt;param name=andquot;Keyandquot;andgt;Item to registerandlt;/paramandgt;<br /><br /><br />      50:         /// andlt;param name=andquot;Constructorandquot;andgt;The function to call when creating the itemandlt;/paramandgt;<br /><br /><br />      51:         public virtual void Register(Key Key, Funcandlt;Tandgt; Constructor)<br /><br /><br />      52:         {<br /><br /><br />      53:             if (Exists(Key))<br /><br /><br />      54:                 Constructors[Key] = Constructor;<br /><br /><br />      55:             else<br /><br /><br />      56:                 Constructors.Add(Key, Constructor);<br /><br /><br />      57:         }<br /><br /><br />      58: <br /><br /><br />      59:         /// andlt;summaryandgt;<br /><br /><br />      60:         /// Creates an instance associated with the key<br /><br /><br />      61:         /// andlt;/summaryandgt;<br /><br /><br />      62:         /// andlt;param name=andquot;Keyandquot;andgt;Registered itemandlt;/paramandgt;<br /><br /><br />      63:         /// andlt;returnsandgt;The type returned by the initializerandlt;/returnsandgt;<br /><br /><br />      64:         public virtual T Create(Key Key)<br /><br /><br />      65:         {<br /><br /><br />      66:             if (Exists(Key))<br /><br /><br />      67:                 return Constructors[Key]();<br /><br /><br />      68:             return default(T);<br /><br /><br />      69:         }<br /><br /><br />      70: <br /><br /><br />      71:         /// andlt;summaryandgt;<br /><br /><br />      72:         /// Determines if a key has been registered<br /><br /><br />      73:         /// andlt;/summaryandgt;<br /><br /><br />      74:         /// andlt;param name=andquot;Keyandquot;andgt;Key to checkandlt;/paramandgt;<br /><br /><br />      75:         /// andlt;returnsandgt;True if it exists, false otherwiseandlt;/returnsandgt;<br /><br /><br />      76:         public virtual bool Exists(Key Key)<br /><br /><br />      77:         {<br /><br /><br />      78:             return Constructors.ContainsKey(Key);<br /><br /><br />      79:         }<br /><br /><br />      80: <br /><br /><br />      81:         #endregion<br /><br /><br />      82:     }<br /><br /><br />      83: }<br /><br /><br /><br /><br /><br />If we compile, we get a line on the screen that just says “B”. Now let’s assume we create another DLL, called Utilities.DLL, with a class called Factory, but instead had it look like this:<br /><br /><br />  <br />       1: using System;<br /><br /><br />       2: using System.Collections.Generic;<br /><br /><br />       3: using System.Linq;<br /><br /><br />       4: using System.Text;<br /><br /><br />       5: <br /><br /><br />       6: namespace Utilities.DataTypes.Patterns<br /><br /><br />       7: {<br /><br /><br />       8:     public class Factoryandlt;Key, Tandgt;<br /><br /><br />       9:     {<br /><br /><br />      10:         #region Constructors<br /><br /><br />      11: <br /><br /><br />      12:         /// andlt;summaryandgt;<br /><br /><br />      13:         /// Constructor<br /><br /><br />      14:         /// andlt;/summaryandgt;<br /><br /><br />      15:         public Factory()<br /><br /><br />      16:         {<br /><br /><br />      17:             Constructors = new Dictionaryandlt;Key, Funcandlt;Tandgt;andgt;();<br /><br /><br />      18:         }<br /><br /><br />      19: <br /><br /><br />      20:         #endregion<br /><br /><br />      21: <br /><br /><br />      22:         #region Protected Variables<br /><br /><br />      23: <br /><br /><br />      24:         /// andlt;summaryandgt;<br /><br /><br />      25:         /// List of constructors/initializers<br /><br /><br />      26:         /// andlt;/summaryandgt;<br /><br /><br />      27:         protected virtual Dictionaryandlt;Key, Funcandlt;Tandgt;andgt; Constructors { get; set; }<br /><br /><br />      28: <br /><br /><br />      29:         #endregion<br /><br /><br />      30: <br /><br /><br />      31:         #region Public Functions<br /><br /><br />      32: <br /><br /><br />      33:         /// andlt;summaryandgt;<br /><br /><br />      34:         /// Registers an item<br /><br /><br />      35:         /// andlt;/summaryandgt;<br /><br /><br />      36:         /// andlt;param name=andquot;Keyandquot;andgt;Item to registerandlt;/paramandgt;<br /><br /><br />      37:         /// andlt;param name=andquot;Resultandquot;andgt;The object to be returnedandlt;/paramandgt;<br /><br /><br />      38:         public virtual void Register(Key Key, T Result)<br /><br /><br />      39:         {<br /><br /><br />      40:             if (Exists(Key))<br /><br /><br />      41:                 Constructors[Key] = () =andgt; MyFunction();<br /><br /><br />      42:             else<br /><br /><br />      43:                 Constructors.Add(Key, () =andgt; MyFunction());<br /><br /><br />      44:         }<br /><br /><br />      45: <br /><br /><br />      46:         /// andlt;summaryandgt;<br /><br /><br />      47:         /// Registers an item<br /><br /><br />      48:         /// andlt;/summaryandgt;<br /><br /><br />      49:         /// andlt;param name=andquot;Keyandquot;andgt;Item to registerandlt;/paramandgt;<br /><br /><br />      50:         /// andlt;param name=andquot;Constructorandquot;andgt;The function to call when creating the itemandlt;/paramandgt;<br /><br /><br />      51:         public virtual void Register(Key Key, Funcandlt;Tandgt; Constructor)<br /><br /><br />      52:         {<br /><br /><br />      53:             if (Exists(Key))<br /><br /><br />      54:                 Constructors[Key] = () =andgt; MyFunction();<br /><br /><br />      55:             else<br /><br /><br />      56:                 Constructors.Add(Key, () =andgt; MyFunction());<br /><br /><br />      57:         }<br /><br /><br />      58: <br /><br /><br />      59:         private T MyFunction()<br /><br /><br />      60:         {<br /><br /><br />      61:             Console.Write(andquot;I deleted something importantandquot;);<br /><br /><br />      62:             return default(T);<br /><br /><br />      63:         }<br /><br /><br />      64: <br /><br /><br />      65:         /// andlt;summaryandgt;<br /><br /><br />      66:         /// Creates an instance associated with the key<br /><br /><br />      67:         /// andlt;/summaryandgt;<br /><br /><br />      68:         /// andlt;param name=andquot;Keyandquot;andgt;Registered itemandlt;/paramandgt;<br /><br /><br />      69:         /// andlt;returnsandgt;The type returned by the initializerandlt;/returnsandgt;<br /><br /><br />      70:         public virtual T Create(Key Key)<br /><br /><br />      71:         {<br /><br /><br />      72:             if (Exists(Key))<br /><br /><br />      73:                 return Constructors[Key]();<br /><br /><br />      74:             return default(T);<br /><br /><br />      75:         }<br /><br /><br />      76: <br /><br /><br />      77:         /// andlt;summaryandgt;<br /><br /><br />      78:         /// Determines if a key has been registered<br /><br /><br />      79:         /// andlt;/summaryandgt;<br /><br /><br />      80:         /// andlt;param name=andquot;Keyandquot;andgt;Key to checkandlt;/paramandgt;<br /><br /><br />      81:         /// andlt;returnsandgt;True if it exists, false otherwiseandlt;/returnsandgt;<br /><br /><br />      82:         public virtual bool Exists(Key Key)<br /><br /><br />      83:         {<br /><br /><br />      84:             return Constructors.ContainsKey(Key);<br /><br /><br />      85:         }<br /><br /><br />      86: <br /><br /><br />      87:         #endregion<br /><br /><br />      88:     }<br /><br /><br />      89: }<br /><br /><br /><br /><br />Instead of having a line that says simply “B”, we’re going to get “I deleted something important”. If I copy this second Utilities.DLL into the location of the first, TestApp will load it without thinking twice. That should make you worry right about now because what if instead of saying “I deleted something important”, I actually went ahead and deleted something important? Now if you sign a DLL (and the other person doesn’t have access to the key), you will not get this issue. Instead you will get a nice error that is thrown saying “can’t load XXXXX.DLL”. If the public keys don’t match, it’s not loaded. If the third party DLLs had been signed my first week at that job would have been a lot easier. So to make things easier on new hires (and to prevent the possibility of some more nefarious possibilities), please sign your DLLs.]]></description>
<itunes:subtitle>Why You Should Sign Your DLLs</itunes:subtitle><itunes:summary><![CDATA[Generally speaking I do not deal with security issues much. I mean I can set up SSL, set up a form based authentication, etc. the basic stuff. But one thing that I almost always do in my applications is sign the DLLs. The main reason I do this is because of a former coworker of mine.  You see, years ago I worked with a guy who liked to mess with people. He liked to put new hires through a “hazing” ritual. Specifically he had this application that he wrote that would analyze a DLL, find the class/functions that were available in the DLL, and generate some default classes with the same names (basically he generated stubs). He would do this with one of the third party DLLs that we were using, slip it onto your machine, and come over and tell you that whatever app you had just shipped wasn’t working correctly. You’d start up the app and nothing would work. It would start up fine, but everything from the one DLL would return null/default values.  The reason he was able to do this was because the way that DLLs are loaded is dumb. I don’t mean it’s done in a stupid way, well it is sort of. When you link to a DLL that is named MyDLLs.dll, it will load anything as long as it has the same name by default. As an example, let’s assume that I have an app called TestApp:             1: using System;<br /><br /><br />       2: using System.Collections.Generic;<br /><br /><br />       3: using System.Linq;<br /><br /><br />       4: using System.Text;<br /><br /><br />       5: using Utilities.DataTypes.Patterns;<br /><br /><br />       6: <br /><br /><br />       7: namespace TestApp<br /><br /><br />       8: {<br /><br /><br />       9:     class Program<br /><br /><br />      10:     {<br /><br /><br />      11:         static void Main(string[] args)<br /><br /><br />      12:         {<br /><br /><br />      13:             Factoryandlt;string, stringandgt; Factory = new Factoryandlt;string, stringandgt;();<br /><br /><br />      14:             Factory.Register(andquot;Aandquot;, andquot;Bandquot;);<br /><br /><br />      15:             Console.WriteLine(Factory.Create(andquot;Aandquot;));<br /><br /><br />      16:             Console.ReadLine();<br /><br /><br />      17:         }<br /><br /><br />      18:     }<br /><br /><br />      19: }<br /><br /><br /><br />It’s simple enough, all it’s doing is using the default System DLLs and one extra DLL called Utilities (and yes, it’s a class from my utility library but let’s assume that it’s not). The Utilities DLL has a class called Factory:<br /><br /><br />  <br />       1: using System;<br /><br /><br />       2: using System.Collections.Generic;<br /><br /><br />       3: using System.Linq;<br /><br /><br />       4: using System.Text;<br /><br /><br />       5: <br /><br /><br />       6: namespace Utilities.DataTypes.Patterns<br /><br /><br />       7: {<br /><br /><br />       8:     public class Factoryandlt;Key, Tandgt;<br /><br /><br />       9:     {<br /><br /><br />      10:         #region Constructors<br /><br /><br />      11: <br /><br /><br />      12:         /// andlt;summaryandgt;<br /><br /><br />      13:         /// Constructor<br /><br /><br />      14:         /// andlt;/summaryandgt;<br /><br /><br />      15:         public Factory()<br /><br /><br />      16:         {<br /><br /><br />      17:             Constructors = new Dictionaryandlt;Key, Funcandlt;Tandgt;andgt;();<br /><br /><br />      18:         }<br /><br /><br />      19: <br /><br /><br />      20:         #endregion<br /><br /><br />      21: <br /><br /><br />      22:         #region Protected Variables<br /><br /><br />      23: <br /><br /><br />      24:         /// andlt;summaryandgt;<br /><br /><br />      25:         /// List of constructors/initializers<br /><br /><br />      26:         /// andlt;/summaryandgt;<br /><br /><br />      27:         protected virtual Dictionaryandlt;Key, Funcandlt;Tandgt;andgt; Constructors { get; set; }<br /><br /><br />      28: <br /><br /><br />      29:         #endregion<br /><br /><br />      30: <br /><br /><br />      31:         #region Public Functions<br /><br /><br />      32: <br /><br /><br />      33:         /// andlt;summaryandgt;<br /><br /><br />      34:         /// Registers an item<br /><br /><br />      35:         /// andlt;/summaryandgt;<br /><br /><br />      36:         /// andlt;param name=andquot;Keyandquot;andgt;Item to registerandlt;/paramandgt;<br /><br /><br />      37:         /// andlt;param name=andquot;Resultandquot;andgt;The object to be returnedandlt;/paramandgt;<br /><br /><br />      38:         public virtual void Register(Key Key, T Result)<br /><br /><br />      39:         {<br /><br /><br />      40:             if (Exists(Key))<br /><br /><br />      41:                 Constructors[Key] = new Funcandlt;Tandgt;(() =andgt; Result);<br /><br /><br />      42:             else<br /><br /><br />      43:                 Constructors.Add(Key, new Funcandlt;Tandgt;(() =andgt; Result));<br /><br /><br />      44:         }<br /><br /><br />      45: <br /><br /><br />      46:         /// andlt;summaryandgt;<br /><br /><br />      47:         /// Registers an item<br /><br /><br />      48:         /// andlt;/summaryandgt;<br /><br /><br />      49:         /// andlt;param name=andquot;Keyandquot;andgt;Item to registerandlt;/paramandgt;<br /><br /><br />      50:         /// andlt;param name=andquot;Constructorandquot;andgt;The function to call when creating the itemandlt;/paramandgt;<br /><br /><br />      51:         public virtual void Register(Key Key, Funcandlt;Tandgt; Constructor)<br /><br /><br />      52:         {<br /><br /><br />      53:             if (Exists(Key))<br /><br /><br />      54:                 Constructors[Key] = Constructor;<br /><br /><br />      55:             else<br /><br /><br />      56:                 Constructors.Add(Key, Constructor);<br /><br /><br />      57:         }<br /><br /><br />      58: <br /><br /><br />      59:         /// andlt;summaryandgt;<br /><br /><br />      60:         /// Creates an instance associated with the key<br /><br /><br />      61:         /// andlt;/summaryandgt;<br /><br /><br />      62:         /// andlt;param name=andquot;Keyandquot;andgt;Registered itemandlt;/paramandgt;<br /><br /><br />      63:         /// andlt;returnsandgt;The type returned by the initializerandlt;/returnsandgt;<br /><br /><br />      64:         public virtual T Create(Key Key)<br /><br /><br />      65:         {<br /><br /><br />      66:             if (Exists(Key))<br /><br /><br />      67:                 return Constructors[Key]();<br /><br /><br />      68:             return default(T);<br /><br /><br />      69:         }<br /><br /><br />      70: <br /><br /><br />      71:         /// andlt;summaryandgt;<br /><br /><br />      72:         /// Determines if a key has been registered<br /><br /><br />      73:         /// andlt;/summaryandgt;<br /><br /><br />      74:         /// andlt;param name=andquot;Keyandquot;andgt;Key to checkandlt;/paramandgt;<br /><br /><br />      75:         /// andlt;returnsandgt;True if it exists, false otherwiseandlt;/returnsandgt;<br /><br /><br />      76:         public virtual bool Exists(Key Key)<br /><br /><br />      77:         {<br /><br /><br />      78:             return Constructors.ContainsKey(Key);<br /><br /><br />      79:         }<br /><br /><br />      80: <br /><br /><br />      81:         #endregion<br /><br /><br />      82:     }<br /><br /><br />      83: }<br /><br /><br /><br /><br /><br />If we compile, we get a line on the screen that just says “B”. Now let’s assume we create another DLL, called Utilities.DLL, with a class called Factory, but instead had it look like this:<br /><br /><br />  <br />       1: using System;<br /><br /><br />       2: using System.Collections.Generic;<br /><br /><br />       3: using System.Linq;<br /><br /><br />       4: using System.Text;<br /><br /><br />       5: <br /><br /><br />       6: namespace Utilities.DataTypes.Patterns<br /><br /><br />       7: {<br /><br /><br />       8:     public class Factoryandlt;Key, Tandgt;<br /><br /><br />       9:     {<br /><br /><br />      10:         #region Constructors<br /><br /><br />      11: <br /><br /><br />      12:         /// andlt;summaryandgt;<br /><br /><br />      13:         /// Constructor<br /><br /><br />      14:         /// andlt;/summaryandgt;<br /><br /><br />      15:         public Factory()<br /><br /><br />      16:         {<br /><br /><br />      17:             Constructors = new Dictionaryandlt;Key, Funcandlt;Tandgt;andgt;();<br /><br /><br />      18:         }<br /><br /><br />      19: <br /><br /><br />      20:         #endregion<br /><br /><br />      21: <br /><br /><br />      22:         #region Protected Variables<br /><br /><br />      23: <br /><br /><br />      24:         /// andlt;summaryandgt;<br /><br /><br />      25:         /// List of constructors/initializers<br /><br /><br />      26:         /// andlt;/summaryandgt;<br /><br /><br />      27:         protected virtual Dictionaryandlt;Key, Funcandlt;Tandgt;andgt; Constructors { get; set; }<br /><br /><br />      28: <br /><br /><br />      29:         #endregion<br /><br /><br />      30: <br /><br /><br />      31:         #region Public Functions<br /><br /><br />      32: <br /><br /><br />      33:         /// andlt;summaryandgt;<br /><br /><br />      34:         /// Registers an item<br /><br /><br />      35:         /// andlt;/summaryandgt;<br /><br /><br />      36:         /// andlt;param name=andquot;Keyandquot;andgt;Item to registerandlt;/paramandgt;<br /><br /><br />      37:         /// andlt;param name=andquot;Resultandquot;andgt;The object to be returnedandlt;/paramandgt;<br /><br /><br />      38:         public virtual void Register(Key Key, T Result)<br /><br /><br />      39:         {<br /><br /><br />      40:             if (Exists(Key))<br /><br /><br />      41:                 Constructors[Key] = () =andgt; MyFunction();<br /><br /><br />      42:             else<br /><br /><br />      43:                 Constructors.Add(Key, () =andgt; MyFunction());<br /><br /><br />      44:         }<br /><br /><br />      45: <br /><br /><br />      46:         /// andlt;summaryandgt;<br /><br /><br />      47:         /// Registers an item<br /><br /><br />      48:         /// andlt;/summaryandgt;<br /><br /><br />      49:         /// andlt;param name=andquot;Keyandquot;andgt;Item to registerandlt;/paramandgt;<br /><br /><br />      50:         /// andlt;param name=andquot;Constructorandquot;andgt;The function to call when creating the itemandlt;/paramandgt;<br /><br /><br />      51:         public virtual void Register(Key Key, Funcandlt;Tandgt; Constructor)<br /><br /><br />      52:         {<br /><br /><br />      53:             if (Exists(Key))<br /><br /><br />      54:                 Constructors[Key] = () =andgt; MyFunction();<br /><br /><br />      55:             else<br /><br /><br />      56:                 Constructors.Add(Key, () =andgt; MyFunction());<br /><br /><br />      57:         }<br /><br /><br />      58: <br /><br /><br />      59:         private T MyFunction()<br /><br /><br />      60:         {<br /><br /><br />      61:             Console.Write(andquot;I deleted something importantandquot;);<br /><br /><br />      62:             return default(T);<br /><br /><br />      63:         }<br /><br /><br />      64: <br /><br /><br />      65:         /// andlt;summaryandgt;<br /><br /><br />      66:         /// Creates an instance associated with the key<br /><br /><br />      67:         /// andlt;/summaryandgt;<br /><br /><br />      68:         /// andlt;param name=andquot;Keyandquot;andgt;Registered itemandlt;/paramandgt;<br /><br /><br />      69:         /// andlt;returnsandgt;The type returned by the initializerandlt;/returnsandgt;<br /><br /><br />      70:         public virtual T Create(Key Key)<br /><br /><br />      71:         {<br /><br /><br />      72:             if (Exists(Key))<br /><br /><br />      73:                 return Constructors[Key]();<br /><br /><br />      74:             return default(T);<br /><br /><br />      75:         }<br /><br /><br />      76: <br /><br /><br />      77:         /// andlt;summaryandgt;<br /><br /><br />      78:         /// Determines if a key has been registered<br /><br /><br />      79:         /// andlt;/summaryandgt;<br /><br /><br />      80:         /// andlt;param name=andquot;Keyandquot;andgt;Key to checkandlt;/paramandgt;<br /><br /><br />      81:         /// andlt;returnsandgt;True if it exists, false otherwiseandlt;/returnsandgt;<br /><br /><br />      82:         public virtual bool Exists(Key Key)<br /><br /><br />      83:         {<br /><br /><br />      84:             return Constructors.ContainsKey(Key);<br /><br /><br />      85:         }<br /><br /><br />      86: <br /><br /><br />      87:         #endregion<br /><br /><br />      88:     }<br /><br /><br />      89: }<br /><br /><br /><br /><br />Instead of having a line that says simply “B”, we’re going to get “I deleted something important”. If I copy this second Utilities.DLL into the location of the first, TestApp will load it without thinking twice. That should make you worry right about now because what if instead of saying “I deleted something important”, I actually went ahead and deleted something important? Now if you sign a DLL (and the other person doesn’t have access to the key), you will not get this issue. Instead you will get a nice error that is thrown saying “can’t load XXXXX.DLL”. If the public keys don’t match, it’s not loaded. If the third party DLLs had been signed my first week at that job would have been a lot easier. So to make things easier on new hires (and to prevent the possibility of some more nefarious possibilities), please sign your DLLs.]]></itunes:summary></item>
<item><title>Setting Up Hg-Git</title>
<link>http://www.gutgames.com/post/Setting-Up-Hg-Git.aspx</link>
<author>James Craig</author>
<pubDate>Thu, 28 Jul 2011 22:22:23 GMT</pubDate>
<description><![CDATA[So apparently it takes the people at CodePlex a little while to make the switch to Mercury from SVN because, as I go to the site now, my code repository is coming up Subversion. It’s only been eight days though since Wade from Chinasoft (who apparently does their tech support) contacted me, and this would fall under low priority, so I’ll give it a little more time but seriously someone needs to automate that process. In the mean time I’ve set up both a bitbucket and github site. Now the bitbucket setup was simple, install TortoiseHg and I’m done. Setting up github was a bit more in depth. I mean I could just set up git, but I hate the command line. Give me a GUI and I’m happy (I know, I’m odd for a programmer). So instead I decided to set up Hg-Git.  Hg-Git is a plugin for mercury that allows you to connect to git repositories and it’s kind of a pain to set up. Well not really. It only takes a couple of steps:     Install TortoiseHg – It’s here    Install Hg-Git – you can use TortoiseHg to get the latest version from the repository here. All you have to do is download it, it’s a bunch of python code so nothing to install.    Now we set it up – Open up TortoiseHg’s Hg Workbench, go to File-andgt;Settings-andgt;Edit File (it’s a button on the upper right side). From there we enter the following and save it:   [extensions]   hggit = Location that you saved Hg-Git to  hgext.bookmarks =  [ui]   ssh = andquot;C:\Program Files\TortoiseHg\TortoisePlink.exeandquot;       Once we do that we need to create a public/private key pair. I used PuTTY for this. Just install it and run the PuTTYgen app, hit Generate, and save the public and private key to your hard drive.    Once the keys are generated, we need to add our key to github. If you go into your Account Settings, there is a link that says SSH Public Keys on the left side. Once there the middle portion should say Add another public key. Copy and paste the public key that you saved earlier into there and hit save.    Now we just need to setup Pageant (it’s installed already at this point). Add a shortcut to the Startup folder with the following:   andquot;C:\Program Files\TortoiseHg\Pageant.exeandquot; andquot;Location of the private key that you saved earlierandquot;<br /><br />From here on you should be able to clone your repository and start pushing code. However I’ve learned that I need to set the master bookmark to whatever I actually want to push for some odd reason. That doesn’t seem like something I should have to do but it is what it is. Anyway, that’s what I went through to get it up and running. For now I’ll be updating the code on those two pages and not the CodePlex page (that will change once they actually update my repository there). So choose whichever you like more and happy coding. Oh and I’ve set it up to link to the Twitter account (sorry for spamming the tests earlier today), so if you want to keep up to date with both my site here and updates as I push them to github/bitbucket you will be able to do that now.<br />]]></description>
<itunes:subtitle>Setting Up Hg-Git</itunes:subtitle><itunes:summary><![CDATA[So apparently it takes the people at CodePlex a little while to make the switch to Mercury from SVN because, as I go to the site now, my code repository is coming up Subversion. It’s only been eight days though since Wade from Chinasoft (who apparently does their tech support) contacted me, and this would fall under low priority, so I’ll give it a little more time but seriously someone needs to automate that process. In the mean time I’ve set up both a bitbucket and github site. Now the bitbucket setup was simple, install TortoiseHg and I’m done. Setting up github was a bit more in depth. I mean I could just set up git, but I hate the command line. Give me a GUI and I’m happy (I know, I’m odd for a programmer). So instead I decided to set up Hg-Git.  Hg-Git is a plugin for mercury that allows you to connect to git repositories and it’s kind of a pain to set up. Well not really. It only takes a couple of steps:     Install TortoiseHg – It’s here    Install Hg-Git – you can use TortoiseHg to get the latest version from the repository here. All you have to do is download it, it’s a bunch of python code so nothing to install.    Now we set it up – Open up TortoiseHg’s Hg Workbench, go to File-andgt;Settings-andgt;Edit File (it’s a button on the upper right side). From there we enter the following and save it:   [extensions]   hggit = Location that you saved Hg-Git to  hgext.bookmarks =  [ui]   ssh = andquot;C:\Program Files\TortoiseHg\TortoisePlink.exeandquot;       Once we do that we need to create a public/private key pair. I used PuTTY for this. Just install it and run the PuTTYgen app, hit Generate, and save the public and private key to your hard drive.    Once the keys are generated, we need to add our key to github. If you go into your Account Settings, there is a link that says SSH Public Keys on the left side. Once there the middle portion should say Add another public key. Copy and paste the public key that you saved earlier into there and hit save.    Now we just need to setup Pageant (it’s installed already at this point). Add a shortcut to the Startup folder with the following:   andquot;C:\Program Files\TortoiseHg\Pageant.exeandquot; andquot;Location of the private key that you saved earlierandquot;<br /><br />From here on you should be able to clone your repository and start pushing code. However I’ve learned that I need to set the master bookmark to whatever I actually want to push for some odd reason. That doesn’t seem like something I should have to do but it is what it is. Anyway, that’s what I went through to get it up and running. For now I’ll be updating the code on those two pages and not the CodePlex page (that will change once they actually update my repository there). So choose whichever you like more and happy coding. Oh and I’ve set it up to link to the Twitter account (sorry for spamming the tests earlier today), so if you want to keep up to date with both my site here and updates as I push them to github/bitbucket you will be able to do that now.<br />]]></itunes:summary></item>
</channel>
</rss>