If you're interested in composite oriented programming, there have been some spikes in .NET (none of them evolved into real projects AFAIK):
http://blog.noop.se/archive/2008/08/27/composite-oriented-programming-spike-on-unity-application-block.aspx In particular, IIRC Anders Noras had an almost literal port of Qi4J (called Qi4#) but I can't find the original article or the code. On Feb 22, 10:32 pm, Jan Limpens <[email protected]> wrote: > My current reasoning is to move towards DynamicActions for the controller > part (still have to get a feeling on how this works with method overrides, > ...) and do all UI transformations via JQuery. > > So a complete plugin would consist of an IDynamicAction and of an > IJsProvider. The view could then ask some IJsProviderResolver service with > the current area/controller/action as a > key.http://myapp/resolveScript?params... > the resulting text could then be inserted into the dom and do it's thing. it > could also hold necessary data for constructing selects and the like. > > This is currently theory only and quite less fancy than what I am reading > here :), but it just might work. > > Hell, I just read this Qi4J tutorials and this seems very nice indeed (if it > wasn't for that verbose Java syntax). True, that with dp it should be > possible to do similar things... > > > > On Mon, Feb 22, 2010 at 9:15 PM, Henrik Feldt <[email protected]> wrote: > > MEF is a way tying things (methods, instances) together, perhaps > > DynamicProxy and Krzysztof’s blog could help? > > >http://kozmic.pl/archive/2009/04/27/castle-dynamic-proxy-tutorial.aspx > > > Qi4J <http://qi4j.org/> has a similar concept regarding composites and > > many layers making up a method; perhaps you could apply similar layers with > > dynamic proxy, one for each type of entity (BookProduct, CarProduct …), or > > have a round robin sort of pool of this objects, with the tenant’s key as a > > hash for which bucket to take the proxy from? A plugin could then be a > > mixin, with dynamic proxy creating a new proxy for it; as long as you don’t > > do thousands of turn on/off of the plugins constantly, the generated code > > would probably not increase the memory footprint too much. You could provide > > a key for each sort of mixin/interceptor and then keep e-tags of the proxys > > where the e-tag denotes the combination of tenant’s interceptors that the > > proxy implements? > > > Another way to enable/disable plugins at runtime, could perhaps be to > > implement the command pattern, typed for each business operation that varies > > depending on client (now not talking entities) – then you could perhaps do a > > “ResolveAll<IAddOrderOperation>()” on the IoC container, where > > IAddOrderOperation : IEquatable, IComparable, push them into a list, sort it > > and then do list.ForEach(applyOp), to your state? You could write your own > > ForEach method with multiple exists (invalid op, invalid rule, invalid > > state, dependency failed, whatever), similar to how the Maybe monad works > > (or the Result<TOut,Tex>whereTOut:IOutcome, TEx :Exception-monad?). > > > Taking the monad concept further, perhaps you could have a collection for > > each tenant, of transformer methods that mutate the state in the monad > > (similar to multiple interceptors, but functional)? These functions could be > > resolved for using MEF, or through interfaces implementing only one method > > similar to how functors work in OCaml? > > > Just some ideas based on the abstract concept of multi-tenancy. :) > > > Cheers, > > > Henrik > > > *From:* [email protected] [mailto: > > [email protected]] *On Behalf Of *Jan Limpens > > *Sent:* den 23 februari 2010 00:33 > > *To:* [email protected] > > *Subject:* Re: Extensible Monorails project > > > Currently I am trying to get this partially done via dynamic actions, but > > I'd want to hear more about this, hammett :) ! > > > On Mon, Feb 22, 2010 at 5:41 PM, Alex Henderson <[email protected]> > > wrote: > > > I'd love to see a blog post on this... I'm treading similar water > > developing extensible applications in monorail. I might start blogging > > about my experiences soon, just so I can get some feedback on our current > > approach and ways to improve it (especially around MEF + IOC Container, and > > approaches for handling disabling/removing plugins are runtime - something > > we currently do have working, but it's not pretty). > > > Cheers, > > > - Alex > > > On Tue, Feb 23, 2010 at 7:22 AM, hammett <[email protected]> wrote: > > > It's a complicated problem. I can see a few ways to solve. but the > > price is increased complexity. Will try to cover this in a blog post > > given that the topic is open ended extensibility.. > > > On Mon, Feb 22, 2010 at 8:44 AM, Jan Limpens <[email protected]> > > wrote: > > > Hello! > > > > I have an administrative interface done in MR for a single client doing > > all > > > kind of crud and more operations using explicit services and or explicit > > or > > > implicit Daos (IArticleDao and IDao<Article, long>) resolved from > > Windsor. > > > > Now this project has grown and I will have to make this application > > > extensible (and am breaking my head over how to attack this). Different > > > tenants will have different extensions to the base domain. For instance a > > > customer who sells cakes will need different properties on their Article > > > implementation than customer who will sell toys. Domain and NHibernate > > wise > > > I think I've got this handled. > > > > From what I see I will have to take care of the full implementation of a > > > certain feature crossing typical layers. So one new feature concerning > > one > > > or a set of changes to the domain model should take care of > > > > View and view logic in JavaScript and brail > > > Controller extensions to the base Controller > > > Service extensions... > > > > in the form of one dll - in the ideal case - dropping it in a certain > > place > > > should autowire it somehow, but this can wait. > > > > What I really am concerned about are the extension points I can provide > > from > > > the administrative interface. > > > > A simple case: > > > > [return: JSONReturnBinder] > > > [Transaction(TransactionMode.Requires)] > > > public virtual IList<SimpleArticle> FullTextSearchAsJson(string > > > fragment, int categoryId, int productGroupId, string orderBy, > > > > SortDirection direction, int maxResults, bool isActive, decimal from, > > > decimal to) > > > { > > > Func<Product, object> func = null; > > > switch (orderBy.ToLowerInvariant()) > > > { > > > case "name": > > > func = (x => x.Name); > > > break; > > > case "id": > > > func = (x => x.Id); > > > break; > > > } > > > var priceRange = new PriceRange(from, to - from); > > > > var articles = articleDao.Find(fragment, categoryId, > > > productGroupId, 0, func, direction, maxResults, 0, isActive, priceRange); > > > var result = articles == null ? null : new > > > List<Product>(articles); > > > if (result == null) return null; > > > var link = new LinkHelper(Context); > > > return result > > > .Select(article => new SimpleArticle(article.Id, > > > article.Name, > > > article.Key, > > > link.Article(article))) > > > .ToList(); > > > } > > > > now we extend the Article class with Properties string ISBN { get; set; } > > > and bool HasISBN { get; } and it becomes the BookArticle class. The above > > > method should also output those two fields. > > > > So to have code reuse, > > > > I'd probably refactor out the actual query part, > > > taking the dao as a parameter, > > > returns my new article sub class > > > and the I'd use an extended SimpleArticle to present my items. > > > luckily there is no real view involved, because I have absolutely no idea > > on > > > how to introduce code reuse in that area. I wished, my entities > > > automagically would create their forms for themselves, but this cannot > > work > > > for more complicated entities, I suppose. > > > > While all of this certainly is doable, it is very non-frameworkey and I > > hate > > > all the coupling this introduces. And the best bet for code reuse in the > > > view area for now is relying on the merge feature of my source control. > > > > Anyone wrote something clever about this? Or is inclined to pass me some > > > good pointers here and now? > > > > Thanks! > > > > -- > > > Jan > > > > -- > > > You received this message because you are subscribed to the Google Groups > > > "Castle Project Users" group. > > > To post to this group, send email to > > [email protected]. > > > To unsubscribe from this group, send email to > > > [email protected]<castle-project-users%2Bun > > > [email protected]> > > . > > > For more options, visit this group at > > >http://groups.google.com/group/castle-project-users?hl=en. > > > -- > > Cheers, > > hammett > >http://hammett.castleproject.org/ > > > -- > > You received this message because you are subscribed to the Google Groups > > "Castle Project Users" group. > > To post to this group, send email to [email protected] > > . > > To unsubscribe from this group, send email to > > [email protected]<castle-project-users%2Bun > > [email protected]> > > . > > For more options, visit this group at > >http://groups.google.com/group/castle-project-users?hl=en. > > > -- > > > You received this message because you are subscribed to the Google Groups > > "Castle Project Users" group. > > To post to this group, send email to [email protected] > > . > > To unsubscribe from this group, send email to > > [email protected]<castle-project-users%2Bun > > [email protected]> > > . > > For more options, visit this group at > >http://groups.google.com/group/castle-project-users?hl=en. > > > -- > > Jan > > > -- > > You received this message because you are subscribed to the Google Groups > > "Castle Project Users" group. > > To post to this group, send email to [email protected] > > . > > To unsubscribe from this group, send email to... > > read more » -- You received this message because you are subscribed to the Google Groups "Castle Project Users" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/castle-project-users?hl=en.
