locked
Need some feedback on architecture RRS feed

  • Question

  • User-164920201 posted

    Hello all,

    I am an architect working on a rather large conversion of a web app that is using asp.net 1.1-3.5, csla 1.x and even 200+ pages of classic asp.  Logic is all over the place, there are more work-arounds then real design etc.  I am trying to promote some good practice and OO principles and so far in my design I have come to the conclusion that ASP.Net MVC (well really model2) will help them get there, mostly on testability and extensibility of the framework.  I have been trying to come to grips with the layering we want and I seem to be at odds with the default layout of new ASP.Net MVC apps.  I have never really been comfortable with having all my layers in one project, mostly because I find developers "cheating" a lot when it comes to where they put logic.  I have also found it easier to work on layers when they are in physically different assemblies.  So my architecture is looking like this:

    Web - ASP.Net MVC with WebForms, some classic asp and other.  I also have (obviously) my controllers, views and view models here.  Some model binders and a Presenters assembly for Passive View stuff with the old webforms.  I am using MVP as a comprimise on the webforms just so we can get logic in a more testable format, my guess is though everything will go MVC, but it will take some time.  Plus, maybe they need webforms to do something they can't do in asp.net mvc, I have not found that to be the case so far though.

    BLL Solution Folder

    -- Service Layer: Own assembly, does the normal service layer stuff like validation, coarse grained, orchestrates domain to do stuff, injects for persistance.   Uses automapper to flatten domain and move into DTO's.  We do have some services, plus I do not like my views in MVC being strongly typed to concrete domain objects.  We use view models instead, but I don't think those belong in the BLL as they are view specific.  So my choice was service layer deals with DTO's and whatever front end uses it can transform those to what they want.

    -- Core: Own assembly, Domain. Right now it's EF 4.0, but comparing that to CSLA and NHibernate.  Biggest issue is lack of developer experience.  They tend to make CSLA do bad things and I am not sure they will have a good time with NHibernate just from the shock of how different it is.  I am doing sort of a model first approach with EF4, but ending up POCO.  I actually like it, nice product.  The biggest problem I am having is the whole buddy class thing when your using the designer (if your not going poco), why can't you just have the designer keep track of meta data too then regeneration wouldn't be an issue? maybe it's more complicated then that.

    -- Validation Layer: Own assembly, has mostly validators and custom data annotations.  I am not sure if I want to move this into the service layer itself, or maybe go with entlib VAB and policy injection.  My team is interested in having an actual rules engine, 3rd party or custom, that they can allow SME's to maintain.  That kind of thing is going to need a lot of testing  so for now I have a separate layer.

    DAL

    -- Not a lot of detail on this, right now just using separated interfaces and repository patterns, if any of you are familiar with Dino Esposito and his book "Architecting Applications for the Enterprise", it's a lot like what he did with the DAL Interface/DataContext object.

    So that's about it for the layering, I have a few questions as I am actually struggling to find examples where people have layered similarly and I know I can't be the only one.  By similarly, I mean just pulling the model stuff out into BLL/DAL.

    1) Am I wrong to not agree with having bll stuff and dal stuff in the same physical assembly as my web app?  I guess my main thought is this app is not just a web app, that is just one front end.  We also have services and even some WPF planned.  I really want to be able to have my service layer on down common for all (to the extend possible).  How did you layer your architecture?

    2) Is the DTO - ViewModel approach appropriate?  It adds a lot of overhead in terms of codebase, but I know these developers will be tempted to put logic where it does not belong.  I see presentation logic in our CSLA entities right now. Id rather it got put into the VM's, at least then it's a bit more like MVVM or PM anyway.  I thought about just adapting my domain to view models (cut the dto out), but then view models in MVC are a lot different then in WPF and in the case of my MVP/Webforms it really would be replaced by Presenters and Interfaces.

    3) On Presenters and Interfaces, has anyone used presenters and interfaces with MVC?  I don't want my controllers doing much more then routing anyway and maybe i can reuse some presentation logic between webforms and views?  Would model binders belong to presenters (in same assembly)?

    4) On validation, I have seen a lot of ways this is being done in ASP.Net MVC.  My only requirement is that it's testable and maintainable, if it's in the UI it's propigated there.  The xVal remote validation is kind of neat.  Can anyone advise?  I don't really want to put anything more then data annotations and primitive validation on my domain objects as we have different web apps that require the same business objects with different "business".  The CSLA entities they have has all sorts of If/Else style validation that different teams put there as a hack to bypass different types of validation, I want to avoid that. 

    5) Can anyone tell me how to load a business object with a required data annotation when the field has no value?  I know that it should result in an error, however I found a need in my service layer to load the object and then validate the annotations (runner) and have the service layer route the error, but automapper couldn't map it from the DTO to the Entity because the field was required.  The only option I could see was to move the annotations from the domain entity to the dto or view model or just not use annotations.  The last thing I want to do is have the same annotation, wich is a rule for all uses (it's a key field), in every view model/interface I have that involves the entity.  Seems not so dry to me, what I have done for now is just not use the required annotation and handled it with a validator instead.

    Any other advice would be appreciated, I am really a lead developer, but I got thrust into the architect role as nobody else had enough experience with design.  I am liking it so far though, this is my favorite part of coding.

    Thanks,

     

    Thursday, April 8, 2010 9:57 AM

All replies

  • User-1916342745 posted

    Hi,

    We've got a few projects running along similar lines.

    Go with framework 4.0, and get the goodness of POCO. I'd run with that if you have the option. MVC2 is good, but we've had a couple of problems with doughnut caching.

    We tend to use seperate phyical projects for separate layers (except for very small projects).

    All views have dedicated models. so a edit model for a "priorioty" object would be Priority_Edit_ViewModel.cs (or similar).

    With a small amount of additional work, you can adapt the t4 templates to do a lot more heaving lifting, and build most of the DTO's, data annotations, and basic controllers for you.

    Watch out for the differences between model binding in mvc2, and input validation in mvc1 (have I got that the right way round?).

    We've had a few issues with scaling automapper. Its not a bad product (and credit to those who have worked so hard on it), but I seem to remember one of my colleagues recently giving it a hard time due to its static restrictions.

    We've used Castle Windsor for IoC, and played a little with Unity and a couple of others. It saves on a bunch of coding, but can make the priciples more complex to grasp for those who are not familiar with IoC.

    We've had a fair few discussions about how to split out the differences between the DAL, and Service layer. Personally I liked to look at the return types. If an item is returning an IEnumerable or list then it should be in the service layer. If its returning an IQueryable, then it should be in the DAL.

    My only other thought is to watch out for object creep with extensions methods/lazy loading.

    Best of luck.

     

     

      

    Monday, April 19, 2010 2:54 PM