<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://experience.fellowshipone.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Intelligent Design : Architecture</title><link>http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Architecture/default.aspx</link><description>Tags &amp; Topics: Architecture</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61120.2)</generator><item><title>Fellowship One REST API - OAuth Security Update</title><link>http://experience.fellowshipone.com/blogs/intelligentdesign/archive/2009/04/23/fellowship-one-rest-api-oauth-security-update.aspx</link><pubDate>Thu, 23 Apr 2009 07:43:00 GMT</pubDate><guid isPermaLink="false">87eee960-b871-44cb-8a98-02588a960c04:14229</guid><dc:creator>FTProductDev</dc:creator><slash:comments>0</slash:comments><comments>http://experience.fellowshipone.com/blogs/intelligentdesign/comments/14229.aspx</comments><wfw:commentRss>http://experience.fellowshipone.com/blogs/intelligentdesign/commentrss.aspx?PostID=14229</wfw:commentRss><description>&lt;b&gt;NOTE: THIS UPDATE ONLY CONCERNS THE FELLOWSHIP ONE RESTFUL API BETA &lt;a href="https://demo.staging.fellowshiponeapi.com/v1/Util/AuthDocs.help#3oauth"&gt;OAUTH IMPLEMENTATION&lt;/a&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;Yesterday a &lt;a href="http://news.cnet.com/8301-13577_3-10225103-36.html"&gt;minor security threat&lt;/a&gt; was discovered in the &lt;a href="http://oauth.net"&gt;OAuth protocol&lt;/a&gt;.&lt;br&gt;&lt;br&gt;The OAuth community is aggressively working on the issue and have released an &lt;a href="http://oauth.net/advisories%20"&gt;advisory update&lt;/a&gt; on this on 4.23.2009 at 12:00 am PST. We have been in contact with them on the details of this issue. After a close look at the threat and considering the risks involved, we have determined that we will not suspend the use of OAuth in our API. Instead, we will immediately implement additional mechanisms to further protect against potential attack:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Shorten the request token life time&lt;/li&gt;&lt;li&gt;Require any 3rd Party application to have a registered callback&lt;/li&gt;&lt;li&gt;Require additional warnings and details on the token authorization pages to clearly explain the intent of the Consumer application &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We take all security-related issues seriously. Although the REST API
OAuth implementation is only available in a beta environment right now,
we want to take mitigating actions.These changes to our OAuth Service Provider implementation will be deployed soon.&lt;br&gt;&lt;/p&gt;&lt;p&gt;We purposely chose OAuth as our primary authentication mechanism because of the security and iron-clad structure it provides. We are even more encouraged by our choice in light of the quick response and reaction from the OAuth community. Since there are thousands of developers and applications behind this protocol, there are thousands of people behind our implementation. &lt;br&gt;&lt;/p&gt;&lt;p&gt;We would like to thank &lt;a href="http://twitter.com/chrismessina"&gt;Chris Messina&lt;/a&gt;, &lt;a href="http://hueniverse.com"&gt;Eran Hammer-Lahav&lt;/a&gt;, and&amp;nbsp; the rest of the OAuth community for being so transparent and quick to respond and collaborate to solve this issue. &lt;br&gt;&lt;/p&gt;&lt;p&gt;Please &lt;u&gt;do not hesitate to contact us&lt;/u&gt; directly with any concerns or questions that you may have: api [at] fellowshiptech.com&lt;br&gt;&lt;br&gt;&lt;b&gt;More information:&lt;/b&gt; see &lt;a href="http://oauth.net/advisories"&gt;OAuth advisories updates&lt;br&gt;&lt;/a&gt;&lt;br&gt;Nick Floyd&lt;br&gt;Integration Architect&lt;br&gt;&lt;/p&gt;&lt;img src="http://experience.fellowshipone.com/aggbug.aspx?PostID=14229" width="1" height="1"&gt;</description><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Fellowship+One/default.aspx">Fellowship One</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/API/default.aspx">API</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/REST/default.aspx">REST</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/RESTful+API/default.aspx">RESTful API</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/OAuth/default.aspx">OAuth</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Protocols/default.aspx">Protocols</category></item><item><title>Fellowship One APIs - Past, Present, and Future</title><link>http://experience.fellowshipone.com/blogs/intelligentdesign/archive/2009/02/25/fellowship-one-apis-past-present-and-future.aspx</link><pubDate>Wed, 25 Feb 2009 22:42:00 GMT</pubDate><guid isPermaLink="false">87eee960-b871-44cb-8a98-02588a960c04:13823</guid><dc:creator>FTProductDev</dc:creator><slash:comments>2</slash:comments><comments>http://experience.fellowshipone.com/blogs/intelligentdesign/comments/13823.aspx</comments><wfw:commentRss>http://experience.fellowshipone.com/blogs/intelligentdesign/commentrss.aspx?PostID=13823</wfw:commentRss><description>&lt;p&gt;With the up coming Fellowship One RESTful API we wanted to take the some time and look back on our other two APIs and reflect on what we intended them to be and what they actually became.&amp;nbsp; We looked at the their interfaces, authentication, resources, versioning, protocols, logging mechanisms, "debuggability", etc...&amp;nbsp; What we found out was that in the world of "API" nothing ever ends up like you intend.&lt;br&gt;&lt;br&gt;&lt;span style="font-weight:bold;"&gt;Fellowship One Data Exchange&lt;/span&gt;:&amp;nbsp; A very powerful XML &lt;a href="http://en.wikipedia.org/wiki/Remote_procedure_call"&gt;RPC API&lt;/a&gt; that was specifically designed to address massive data import and export needs.&amp;nbsp; It's ridged pinpoint interface allow users to build simple data presses, which move large amounts of data between disparate systems.&amp;nbsp; A few years into the product's life we introduced the ability to do synchronous transactions - a decision that completely changed many consumer's usage patterns.&lt;br&gt;&lt;br&gt;Serendipity
stepped in and instantly consumers began to use this brute force
application on websites to perform anything&amp;nbsp; from profile updates to
seamless login patterns.&amp;nbsp; After seeing how much the community found value in the login metaphor we've published docs and given presentations on the best practices of this approach. We now have 3rd parties writing web
applications and hosting web sites that do a myriad of things.&lt;/p&gt;&lt;p&gt;&amp;nbsp;Being a &lt;a href="http://en.wikipedia.org/wiki/SOAP"&gt;SOAP &lt;/a&gt;based .NET web service, consuming Data Exchange required the language to either have a library that constructs SOAP envelopes or that the developer understand that protocol and be able to construct a SOAP message manually.&lt;/p&gt;&lt;p&gt;Another characteristic of this API are the logging and response mechanisms; both were intended to only be used / interpreted by the consuming application.&amp;nbsp; Its authentication is based on simple credential / key maps.&lt;br&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;span style="font-weight:bold;"&gt;Fellowship One Payment Gateway&lt;/span&gt;: A .NET SOAP based web service that gives churches the ability to submit giving / e-commerce transactions.&amp;nbsp; The interesting thing about this service is that it was originally developed for internal consumption only and later opened up to external consumers for book stores, tithe applications, etc... another decision point that changed the way an established API was used.&lt;/p&gt;&lt;p&gt;Payment Gateway answered a changeling question of: "how do I get all of my billing and payments to go through one channel and be able to report on the transactions going through that channel?"&amp;nbsp; Much like Data Exchange, we saw it consumed in ways we couldn't have imagined.&lt;/p&gt;&lt;p&gt;We used credential and signed key authentication for this API.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&amp;nbsp;Fellowship One RESTful API:&lt;/b&gt; A REST based web application that uses several open protocols and patterns to provide consumers access to secure resources. &amp;nbsp;&lt;/p&gt;&lt;p&gt;STANDARDS, PROTOCOLS, and PATTERNS - nothing else.&amp;nbsp; Looking back, we could see where their is major value in sticking with something that is "tried and true."&amp;nbsp; If we could use &lt;u&gt;web based&lt;/u&gt; patterns and protocols for a &lt;u&gt;web based&lt;/u&gt; API we could not only get instant adoption but gain the efficiencies and effectiveness of technologies that "just work."&amp;nbsp; &lt;/p&gt;&lt;p&gt;This next generation of API is, ironically based on foundations that have been in place for years. &amp;nbsp; We chose &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;MVC &lt;/a&gt;as the application architecture, &lt;a href="http://oauth.net/core/1.0/"&gt;OAUTH&lt;/a&gt; protocol for Authentication, &lt;a href="http://www.ics.uci.edu/%7Efielding/pubs/dissertation/rest_arch_style.htm"&gt;REST&lt;/a&gt; and &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html"&gt;HTTP 1.1&lt;/a&gt; as the transport.&amp;nbsp; This API should give web developers an tool where all they have to think about is what to do with the resources.&amp;nbsp; &lt;/p&gt;&lt;p&gt;Thank you for partnering with us over the years; we have a lot of fun stuff up ahead and we hope to see you at the &lt;a href="http://www.dynamicchurchconference.com/developers"&gt;Dev track&lt;/a&gt; @ DC09!&lt;br&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://experience.fellowshipone.com/aggbug.aspx?PostID=13823" width="1" height="1"&gt;</description><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/MVC/default.aspx">MVC</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/development/default.aspx">development</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/API/default.aspx">API</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/DataExchange/default.aspx">DataExchange</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/REST/default.aspx">REST</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/RESTful+API/default.aspx">RESTful API</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Payment+Gateway/default.aspx">Payment Gateway</category></item><item><title>Innovating with MVC in ASP.NET</title><link>http://experience.fellowshipone.com/blogs/intelligentdesign/archive/2007/11/01/innovating-with-mvc-in-asp-net.aspx</link><pubDate>Thu, 01 Nov 2007 00:55:00 GMT</pubDate><guid isPermaLink="false">87eee960-b871-44cb-8a98-02588a960c04:8964</guid><dc:creator>FTProductDev</dc:creator><slash:comments>0</slash:comments><comments>http://experience.fellowshipone.com/blogs/intelligentdesign/comments/8964.aspx</comments><wfw:commentRss>http://experience.fellowshipone.com/blogs/intelligentdesign/commentrss.aspx?PostID=8964</wfw:commentRss><description>&lt;P&gt;If you were following our blog at the end of last year, you read my entry on MVC -&amp;nbsp;&lt;A class="" href="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/2006/09/22/Enterprise-.NET-architecture.aspx"&gt;Wrestling an Enterprise Architecture out of .NET&lt;/A&gt;.&amp;nbsp; Well, we pressed forward and developed a fully-working MVC2 architecture on top of ASP.NET.&amp;nbsp; We've had some bumps along the way, but we think it's been worth&amp;nbsp;the effort&amp;nbsp;to move to an MVC2 architecture.&amp;nbsp; The benefit of moving the majority of your application's logic into controllers cannot be overstated.&amp;nbsp; Testing and API extensibility are just a couple of the huge benefits.&amp;nbsp; We said as much to Scott Guthrie in an email conversation at the beginning of this year, and asked why Microsoft didn't address this architectural need.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;We were very pleased to hear that Microsoft is going to do just that with their &lt;A class="" href="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx"&gt;MVC framework in ASP.NET&lt;/A&gt;, and it feels good to know we were ahead of the curve.&amp;nbsp; Matt Vasquez and I also had the honor of attending a Software Design Review of MVC and some other technologies, along with about 20 others, in Redmond last week.&amp;nbsp; It was a great event, with tons of info on upcoming technologies and some good conversations with the developers.&amp;nbsp; Not to mention the fact that a thirty second question to Scott Guthrie after dinner solved a problem that our development team has spent at least a collective 24 hours trying to figure out.&amp;nbsp; While everything covered in the SDR is under a non-disclosure, suffice it to say that we're excited about this new MVC support from Microsoft.&amp;nbsp;&amp;nbsp;Our home-grown architecture is very legitimized by what we saw.&amp;nbsp; We're very close to what they've developed, but I'm sure we'll be able to use a lot of what they're creating to more cleanly handle what we had to hack onto ASP.NET.&amp;nbsp; It's also exciting to be able to influence the development of this new framework.&amp;nbsp; I plan on cranking some code from the SDR bits starting this weekend and giving lots of juicy feedback.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;I pray that all our customers know that we place a great deal of importance on innovation.&amp;nbsp; It's a high priority for us to innovate both&amp;nbsp;our architecture and our processes to improve our product, and we aren't afraid to go to the lengths necessary to align our development with future-thinking choices.&amp;nbsp; It takes a pioneering spirit to not only see where technology needs to go, but to also take the effort/time/risk to move in that direction.&amp;nbsp; This past year, we moved to the Agile process of &lt;A class="" href="http://en.wikipedia.org/wiki/Scrum_(development)"&gt;Scrum&lt;/A&gt; and created our own MVC architecture on top of ASP.NET.&amp;nbsp; All of our new development now adhears to the MVC pattern (MVC2 if you want to be specific).&amp;nbsp; God has given us a pioneering spirit, and we're excited about where He's leading us.&lt;/P&gt;
&lt;P&gt;thardy&lt;/P&gt;&lt;img src="http://experience.fellowshipone.com/aggbug.aspx?PostID=8964" width="1" height="1"&gt;</description><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/MVC/default.aspx">MVC</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Framework/default.aspx">Framework</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Scrum/default.aspx">Scrum</category></item><item><title>Typed Navigation</title><link>http://experience.fellowshipone.com/blogs/intelligentdesign/archive/2007/01/09/Typed-Navigation.aspx</link><pubDate>Tue, 09 Jan 2007 17:12:00 GMT</pubDate><guid isPermaLink="false">87eee960-b871-44cb-8a98-02588a960c04:808</guid><dc:creator>thardy</dc:creator><slash:comments>0</slash:comments><comments>http://experience.fellowshipone.com/blogs/intelligentdesign/comments/808.aspx</comments><wfw:commentRss>http://experience.fellowshipone.com/blogs/intelligentdesign/commentrss.aspx?PostID=808</wfw:commentRss><description>&lt;p&gt;One of the features we&amp;#39;ve worked into our new home-grown architecture&amp;nbsp;is typed navigation.&amp;nbsp; Without typed navigation,&amp;nbsp;urls are strewn throughout the code, and any changes to navigation or querystrings involve updates to many pages. &amp;nbsp;Not only that, providing a page the data it needs to properly initialize can be difficult to manage and very easy to misunderstand by a developer who is working in a page they&amp;#39;re not familiar with.&amp;nbsp; These issues cause navigation edits to be error-prone and reduce maintainability and extensibility.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The Need&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Consider the following common scenario - You&amp;#39;ve got a page (let&amp;#39;s say EmployeeDetail.aspx) that requires an EmployeeID be passed to it.&amp;nbsp; There are many different ways to get the ID to the page:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;QueryString - EmployeeDetail.aspx?empID=100&lt;/li&gt;&lt;li&gt;Session - Session[&amp;quot;EmployeeID&amp;quot;] = 100&lt;/li&gt;&lt;li&gt;Database retrieval&lt;/li&gt;&lt;li&gt;etc...&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Each method involves different code to set and retrieve the value.&amp;nbsp; In addition, almost every app uses multiple methods in different places and in different scenarios.&amp;nbsp; This results in too many decisions being made by too many different developers, which results in maintenance nightmares.&amp;nbsp; Strict processes can mitigate some of the maintenance pain,&amp;nbsp;if all of your developers ALWAYS use the exact same mechanism, but what about extensibility?&amp;nbsp; What if the page name needs to change at some point?&amp;nbsp; What if you decide to change the way you handle data transfer between pages?&amp;nbsp; Or, more commonly, what if a page simply changes the data it needs or accepts?&lt;/p&gt;&lt;p&gt;Cascading Style Sheets (CSS) is a good example of an architecture with big benefits in UI design - you can make a style change in one place, and that change gets applied in all pages where that style is used.&amp;nbsp; The same measuring stick can be applied to all architectures - can you make a configuration change in a few places (preferably one), and have it applied in all areas of usage?&amp;nbsp; I think most apps would fail this measure in the area of navigation.&amp;nbsp; If a page name changes, most application architectures would require manual changes in many pages - links, code behind redirects, data tables, etc.&amp;nbsp; Even more architectures would fail the test if a change is made to how data is transferred.&amp;nbsp; If a QueryString value changes from empID, to eID, how many code changes would need to be made?&amp;nbsp; What if a page now requires an orgID?&amp;nbsp; Or how about if you move from QueryString to Session, or vice versa?&amp;nbsp; This is where good architectures shine in the long run.&amp;nbsp; Yes you can continue to change the font&amp;nbsp;manually in all your pages when your app is small, but heavy usage of CSS is now widely accepted as best-practice simply because style maintenance and extensibility become absolutely crazy as the number of pages in your site gets large.&amp;nbsp; Why should navigation be any different?&amp;nbsp; It gets just as crazy as your app gets large, and can benefit just as much&amp;nbsp;from a consolidated architecture.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The Solution&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Our solution is to use typed navigation.&amp;nbsp; There are several potential architectures available, one of which is &lt;a href="http://metasapiens.com/PageMethods/"&gt;PageMethods&lt;/a&gt;.&amp;nbsp; There&amp;#39;s a great list of the benefits of typed navigation on that page, so I&amp;#39;ll try not to rehash all of them here.&amp;nbsp; We took a good look at this&amp;nbsp;solution before developing our own architecture, but decided we wanted much more control over our navigation.&amp;nbsp; Also, the PageMethods solution is locked into generating urls with QueryStrings, and it involves&amp;nbsp;pages calling specific methods in other pages, which our new architecture steers clear of&amp;nbsp;due to MVC principles.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Our architecture includes the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Typed Location objects - every navigation destination (View) has its own Location class&lt;/li&gt;&lt;li&gt;Each Location&amp;nbsp;class defines a constant &amp;quot;ViewName&amp;quot; which maps to a url defined in a database, so no urls or page names are ever written in code&amp;nbsp; &lt;/li&gt;&lt;li&gt;Each Location&amp;nbsp;class can have multiple constructors - the constructors provide all the contracts to create&amp;nbsp;the View and allow pages to fulfill multiple roles (list/detail based on what data is sent to them)&lt;/li&gt;&lt;li&gt;Usage in links - a new Location object is created in code-behind and used to set&amp;nbsp;the&amp;nbsp;Location property on one of our HyperLink controls.&amp;nbsp; If set,&amp;nbsp;the HyperLink control has the Location&amp;nbsp;generate its URL when the control is rendered.&amp;nbsp; &lt;/li&gt;&lt;li&gt;Usage in server-side redirects - a controller simply creates a new Location object and calls a&amp;nbsp;public Navigate method on its View &lt;/li&gt;&lt;li&gt;Hydrating Location objects - our base Page class takes care of rehydrating the location object and transferring its data to the View&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Here are the only two options a developer will see regarding Navigation in our app:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;For a HyperLink:&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;font face="courier new,courier"&gt;lnkEmployeeDetail.Location = new EmployeeDetailLocation(employeeID);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;For a server-side redirect:&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;font face="courier new,courier"&gt;_myView.Navigate(new EmployeeDetailLocation(employeeID));&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Since all this is handled by the architecture, changes can be made in just a few places and totally change the Navigation mechanism.&amp;nbsp; We can switch from QueryStrings to Session variables, or rewrite URLs, or change how we rewrite URLs as often as we want.&amp;nbsp; No code that actually uses the Navigation would ever need to change, and&amp;nbsp;page names can change without missing a beat.&amp;nbsp;&amp;nbsp;All the code written to create strongly-typed Location objects would continue to navigate as usual.&amp;nbsp;&amp;nbsp;If a page&amp;#39;s initialization requirements changed, then code would break at compile time instead of runtime, with a very clear and self-describing explanation of exactly how the new Location object needs to be constructed.&amp;nbsp; That&amp;#39;s a lot better than having some forgotten link deep in your app with an obsolete parameter definition getting discovered by a customer after you&amp;#39;ve published your app to production.&lt;/p&gt;&lt;p&gt;Typed Navigation is one more step we&amp;#39;re taking to make our code easy to work with and understand, regardless of how long it&amp;#39;s been since anyone&amp;#39;s&amp;nbsp;touched it,&amp;nbsp;how many developers have had their hands in it, or how large it grows.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://experience.fellowshipone.com/aggbug.aspx?PostID=808" width="1" height="1"&gt;</description><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/.NET/default.aspx">.NET</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Navigation/default.aspx">Navigation</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Framework/default.aspx">Framework</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/URL/default.aspx">URL</category></item><item><title>Persistence via Attributes</title><link>http://experience.fellowshipone.com/blogs/intelligentdesign/archive/2006/10/20/Persistence-via-Attributes.aspx</link><pubDate>Fri, 20 Oct 2006 13:12:00 GMT</pubDate><guid isPermaLink="false">87eee960-b871-44cb-8a98-02588a960c04:560</guid><dc:creator>thardy</dc:creator><slash:comments>0</slash:comments><comments>http://experience.fellowshipone.com/blogs/intelligentdesign/comments/560.aspx</comments><wfw:commentRss>http://experience.fellowshipone.com/blogs/intelligentdesign/commentrss.aspx?PostID=560</wfw:commentRss><description>&lt;p&gt;In the new architecture we&amp;#39;ve been developing, one of the features we&amp;#39;ve developed is a common persistence mechanism.&amp;nbsp; Once again, our attempts are to make development as clear and painless as possible.&amp;nbsp; We want to make it incredibly easy to write good code, and difficult to make mistakes.&amp;nbsp; As our development team grows and code authors move on to other things and other devs&amp;nbsp;end up maintaining that code, we want it to be downright difficult to misunderstand or misuse anything.&lt;/p&gt;&lt;p&gt;Persistence is one area that we&amp;#39;ve seen misused in the past.&amp;nbsp; Basically, anyone can put anything in Session or ViewState from almost anywhere they want.&amp;nbsp; Well, they can from the code-behind of pages, which, like I discussed earlier, ends up getting a great deal of logic thrown in there.&amp;nbsp; We decided to put a stop to this in our new architecture.&lt;/p&gt;&lt;p&gt;We&amp;#39;ve refactored all the persistence code into base classes, and we&amp;#39;re using attributes to decorate our View properties like the following:&lt;/p&gt;&lt;p style="font-family:courier;"&gt;[Persist(PersistenceType.Session)]&lt;br /&gt;public int IndividualID {get{} set{}}&lt;/p&gt;&lt;p&gt;This allows us to very simply specify what needs to be persisted and how.&amp;nbsp; Currently the three different methods of persistence we&amp;#39;re starting with are - ViewState, Session, and Process.&lt;/p&gt;&lt;p&gt;ViewState - this one is pretty self-explanatory&lt;/p&gt;&lt;p style="font-family:courier;"&gt;[Persist(PersistenceType.ViewState)] &lt;/p&gt;&lt;p&gt;Session - this is for page-level session only.&amp;nbsp; It persists the data for as long as the user doesn&amp;#39;t navigate to a different page.&amp;nbsp; The fact that we&amp;#39;ve refactored all our persistence code allows us to implement a very aggressive state management strategy that deletes any session data that does not EXPLICITLY belong at any given time.&lt;/p&gt;&lt;p style="font-family:courier;"&gt;[Persist(PersistenceType.Session)] &lt;/p&gt;&lt;p&gt;Process - this is for state that needs to be maintained across pages.&amp;nbsp; If a page wants to enlist in a shared-state scenario (like a wizard or any sequence of pages the user can move back and forth between).&amp;nbsp; The developer just passes the name of the process to the attribute&amp;#39;s constructor, which assumes a&amp;nbsp;Process persistence.&amp;nbsp; Once again, due to aggressive state management, we immediately delete any process data that isn&amp;#39;t explicitly enlisted in by the currently loading page.&lt;/p&gt;&lt;p style="font-family:courier;"&gt;[Persist(ProcessList.RegistrationProcess)] &lt;/p&gt;&lt;p&gt;For state that needs to be persisted across the user&amp;#39;s entire session, our base Page class will maintain this responsibility.&amp;nbsp; No other code should have this capability.&amp;nbsp; Also note that nothing in our Controllers or business layer can push anything to persistent state.&amp;nbsp; Those layers deal with explicit instructions and methods, some of which may store things in the database, etc, but there&amp;#39;s no concept of a Controller saying, &amp;quot;I want this to be placed in persistent state&amp;quot;.&amp;nbsp; Controllers just manipulate properties and expect them to be stateful.&amp;nbsp; It&amp;#39;s up to the presentation layer to decide how something should be persisted.&amp;nbsp; The difference between WinForms and WebForms is so great that the idea of placing that logic in the Controller makes no sense to us.&lt;/p&gt;&lt;p&gt;As to the performance issues of using Reflection to read and act upon attributes, we feel it&amp;#39;s negligable compared to the benefits.&amp;nbsp; We ran some simple tests, and found that using Attribute-based persistence was approximately 100 times slower than not using Attributes.&amp;nbsp; While that may sound huge, it&amp;#39;s not when you&amp;#39;re talking about the difference (in the worst case) between .00281 and .000228 seconds.&amp;nbsp; Or, in a longer running scenario, between .000268 and .0000363.&amp;nbsp; Not only that, but we&amp;#39;ve researched several methods to make long-running reflection usage far more performant via the use of Reflection.Emit and also ASP.NET 2.0&amp;#39;s Dynamic Methods.&amp;nbsp; Once we&amp;#39;ve solidified other areas of our new architecture, we can go back and tighten the screws.&lt;/p&gt;&lt;p&gt;These changes will increase the visibility and maintainability&amp;nbsp;of our code by allowing any developer to very quickly see exactly what is persisted and how.&amp;nbsp;&amp;nbsp;Having all our persistence logic refactored into one place will eliminate any potential mistakes a developer could make in persisting data, and will increase our agility in extending the functionality in the future.&amp;nbsp; The point is, there&amp;#39;s too much to gain from Reflection not to use it.&lt;/p&gt;&lt;img src="http://experience.fellowshipone.com/aggbug.aspx?PostID=560" width="1" height="1"&gt;</description><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/.NET/default.aspx">.NET</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/State/default.aspx">State</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Persistence/default.aspx">Persistence</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Attributes/default.aspx">Attributes</category></item><item><title>Wrestling an Enterprise Architecture out of .NET</title><link>http://experience.fellowshipone.com/blogs/intelligentdesign/archive/2006/09/22/Enterprise-.NET-architecture.aspx</link><pubDate>Fri, 22 Sep 2006 23:24:00 GMT</pubDate><guid isPermaLink="false">87eee960-b871-44cb-8a98-02588a960c04:219</guid><dc:creator>thardy</dc:creator><slash:comments>3</slash:comments><comments>http://experience.fellowshipone.com/blogs/intelligentdesign/comments/219.aspx</comments><wfw:commentRss>http://experience.fellowshipone.com/blogs/intelligentdesign/commentrss.aspx?PostID=219</wfw:commentRss><description>&lt;p&gt;As a growing &amp;quot;Software as a Service&amp;quot; (SaaS) development shop using .NET we&amp;#39;ve encountered many growing pains and some of the speed bumps inherent in&amp;nbsp;the architecture that many others probably have as well.&amp;nbsp;&amp;nbsp;I&amp;#39;d like to express some of the issues we&amp;#39;ve encountered and hear if anyone else would like to start a dialog on the shortcomings and potential solutions to scaling enterprise .NET development.&amp;nbsp; &lt;/p&gt;&lt;h3&gt;The bigger the code, the bigger the problems&amp;nbsp;&lt;/h3&gt;&lt;p&gt;The typical architectures espoused by .NET aren&amp;#39;t well-designed for large, &amp;quot;always-on&amp;quot;&amp;nbsp;apps.&amp;nbsp;&amp;nbsp;This has become clear to us as our development group and our codebase have grown.&amp;nbsp; SaaS is a big factor here as well, since best-practice is quickly discovered to be a rather tight, incremental release schedule.&amp;nbsp; As our development group scales, and feature demands increase, the framework everything is written in begins to show its strengths and weaknesses.&amp;nbsp; It&amp;#39;s the sort of thing that is difficult to see until many hands have been in the same pot over a period of years.&amp;nbsp; J2EE seems much more geared towards large, enterprise apps, with more emphasis on strict contracts and black boxes.&amp;nbsp;&amp;nbsp;While many of the Java frameworks seem like overkill to most .NET developers, it&amp;#39;s because most .NET developers don&amp;#39;t work on the same codebase for more than a year or two.&amp;nbsp; It seems like Microsoft has made a calculated move to aim squarely between the enterprise and the PHP-type developer&amp;nbsp;communities.&amp;nbsp; We love .NET tools though, and are looking at some foundational architecture changes to tackle these issues.&lt;/p&gt;&lt;h3&gt;Misplaced intelligence&amp;nbsp;&lt;/h3&gt;&lt;p&gt;One of the key difficulties introduced with .NET is the Page-Controller Pattern.&amp;nbsp; Despite how nice and elegant the most common n-Tier .NET architecture sounds on paper, practice shows that a great deal of intelligence (WAY TOO MUCH intelligence) inherently ends up in the code-behind of your pages and user controls, and thus, smack in the middle of your presentation layer.&amp;nbsp; This produces a tight coupling between the presentation and business layers and a lot of business logic in the wrong place.&amp;nbsp;&amp;nbsp;The commonly espoused reason for decreasing this coupling is the ability to completely change the UI layer - say, to take your existing business layer that you used with your Web pages and slap WinForms directly on top of it.&amp;nbsp; While this would be wonderful, the more pressing reason is the simple need to refactor code for maintainability and extensibility.&amp;nbsp; Anything in your code behind pages cannot be reused elsewhere.&amp;nbsp; While having nice business methods in your business layer like &amp;quot;FetchOrdersByCustomer&amp;quot;, or &amp;quot;UpdateProducts&amp;quot; that deal with&amp;nbsp;nice typed objects and collections may make you feel all warm and fuzzy because you have your n-tier bases covered, your architecture bases really aren&amp;#39;t covered at all.&amp;nbsp; Or maybe you have your entities possess the intelligence to manipulate themselves.&amp;nbsp; Either way, the majority of custom development occurs within the consumers of these methods.&amp;nbsp;&amp;nbsp;If the consumers of these methods are in your code behind, you will have real problems as your product grows, your development team grows, and the demands on your product begin to pull it in multiple directions.&amp;nbsp; What you really want is an incredibly stupid presentation layer that only has intelligence about itself.&amp;nbsp; It should only know how to present information from a strictly contracted model it knows nothing about manipulating, how to manage state between &amp;quot;locations&amp;quot; (pages, winforms, pocketPC forms, etc), and how to handle client-side behavior.&amp;nbsp; This is another argument for stupid entities as well (our entities do not know how to manipulate themselves), since our presentation layer can reference our entities without having to worry about exposing all that business logic to the presentation layer.&amp;nbsp; I&amp;#39;m sure I&amp;#39;ll get some disagreements on that, but that&amp;#39;s the beauty of hearing other people&amp;#39;s opinions.&lt;/p&gt;&lt;h3&gt;A possible solution&lt;/h3&gt;&lt;p&gt;The solution we are developing is moving towards something closer to the Model View Controller pattern.&amp;nbsp; Particularly MVC2, which is the same pattern altered for the web.&amp;nbsp; Microsoft&amp;#39;s User Interface Application Block is an MVC block, but MVC does not work on the web.&amp;nbsp; MVC depends on the View being directly updatable from changes to the model, so that combined with the complexity of that application block make it unfeasable for our use.&amp;nbsp; Since the web is stateless, there is no way to directly update your UI from changes to the model.&amp;nbsp; What MVC2 does is simply insert the controller into the process coming from both directions (web to model, and model to web).&amp;nbsp; Microsoft has no packaged solution for anything close to MVC2, which is really disappointing, since you would think they&amp;#39;d want to compete more directly with J2EE and fill this gaping architectural hole.&amp;nbsp; There are some packaged solutions from third parties (even more evidence of a serious development need unmet by Microsoft), such as Maverick.NET &lt;a href="http://mavnet.sourceforge.net/"&gt;http://mavnet.sourceforge.net/&lt;/a&gt;, MonoRail &lt;a href="http://www.castleproject.org/index.php/MonoRail"&gt;http://www.castleproject.org/index.php/MonoRail&lt;/a&gt;,&amp;nbsp;and&amp;nbsp;something called NWAF &lt;a href="http://sourceforge.net/projects/nwaf"&gt;http://sourceforge.net/projects/nwaf&lt;/a&gt;, but all of the above&amp;nbsp;take rather radical departures from the .NET way of doing things and are a big jump for .NET developers.&amp;nbsp; Things like the basic page lifecycle and ViewState are radically changed.&amp;nbsp; We wanted something that wasn&amp;#39;t quite a big leap for our group, yet still gave the major benefits of MVC2.&amp;nbsp; &lt;/p&gt;&lt;p&gt;There has been a pattern that has recently risen to the top of the .NET pattern circles called Model View Presenter (MVP) that attempts to take a stab at MVC2 and still maintain WebForms and ViewState management.&amp;nbsp; I&amp;#39;ve recently read a few articles that mention Microsoft&amp;#39;s CAB (Component UI Application Block) will have some MVP patterns in it, but we&amp;#39;re not holding our breath.&amp;nbsp; It&amp;#39;s also targeted at Smart Clients, so I don&amp;#39;t know how practical it is for pure web-based apps.&lt;/p&gt;&lt;p&gt;We&amp;#39;re building our own home-grown version of an MVP architecture for all development going forward.&amp;nbsp;We are also baking in&amp;nbsp;a few more things that we feel are important, such as:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Typed navigation - urls should never appear in code, and it would be nice if the developer knew the exact state data required in order to navigate to that location/view at compile time&lt;/li&gt;&lt;li&gt;Removing all state-management concerns from the Controller layer - controllers should not care anything about how state is persisted or even have to make the decision that something should be persisted.&amp;nbsp; They should just be able to expect the properties on the View to be available.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As we get further along, I&amp;#39;ll post some of the pitfalls and breakthroughs we come across.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://experience.fellowshipone.com/aggbug.aspx?PostID=219" width="1" height="1"&gt;</description><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/View/default.aspx">View</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/MVC2/default.aspx">MVC2</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/MVP/default.aspx">MVP</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Model/default.aspx">Model</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Controller/default.aspx">Controller</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/MVC/default.aspx">MVC</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Presenter/default.aspx">Presenter</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://experience.fellowshipone.com/blogs/intelligentdesign/archive/tags/.NET/default.aspx">.NET</category></item></channel></rss>