SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)

    Smile Need MVC expert to verify I am on right track.

    After much though and deliberation, I have come to some decisions regarding my mvc project. I have reasons why I decided on my persistence engine over others and why I chose to perform injection the way I did. Overlook these two issues and simple address the rest. What I'd like you to do, is take a look at this preliminary code (major code base is saved). Tell me if I am getting the basic thought process correct in regards to repositories, services, models, and views. Also take a look at my specifications, filters, extensions and engines. Give me any feedback here before I proceed with the rest of the app.

    Note: No db scripts provided. Do not attempt to run this app.
    Attached Files Attached Files

  2. #2
    SitePoint Wizard
    Join Date
    Apr 2007
    Posts
    1,398
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    uh... I think you maybe expecting too much of us to digg inside your code. Instead of that, if you could provide Overall High Level Design Diagram or Simplified version of Class Diagram would definitely help. At least that's just my opinion.

  3. #3
    ALT.NET - because we need it silver trophybronze trophy dhtmlgod's Avatar
    Join Date
    Jul 2001
    Location
    Scotland
    Posts
    4,836
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Looks ok to me, a little cluttered in the root directory, I would move stuff that's not directly Mvc related into a different folder (we usually use /Core) or a different project. And please don't use poor man's DI http://www.lostechies.com/blogs/chad...injection.aspx

  4. #4
    SitePoint Author silver trophybronze trophy
    wwb_99's Avatar
    Join Date
    May 2003
    Location
    Washington, DC
    Posts
    10,625
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Using DI would require using libraries written by other people . . ..

  5. #5
    ALT.NET - because we need it silver trophybronze trophy dhtmlgod's Avatar
    Join Date
    Jul 2001
    Location
    Scotland
    Posts
    4,836
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can write a really basic IoC container in < 100LOC, essentially it just boils down to a Dictionary of types

  6. #6
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    Sorry, I've been without internet the past few days. I would've been here to respond otherwise.

    In response to wwb:

    I don't have a problem with things written by others. Most of the MVC framwork is contributed material. The difference is that MS adopted it and put their name on it. That's enough for me.

    In response to dhtml:

    Over this past week, while my inet was down, I tore this app apart. Several times in fact. My analysis comes down to the following.

    [Edit] I hit enter too soon, continuation coming up...

  7. #7
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    [Continuation from last post]

    Objective for this app:

    1) Follow the K.I.S.S principle in every step of development.

    2) Keep the number of methods, classes, and projects to a minimum.

    3) Only use design patterns that actually benefit my efforts.

    4) Stick to an "out of the box" VS solution.

    Ok, so those four things really had an impact on my project.

    First off, wanting to stick purely with MS stuff, my choices for database were limited, but of course I chose SQLExpress.

    Second, choices for persistence engine were OdbcClient, SqlClient, Linq2Sql, and Entity Framework. I ruled the first two out as they would be more work (even though using an odbc driver had it's appeal). The last two were faily similar, but Linq2Sql won out because of some nice features the other doesn't have (to my knowledge). Namely, the ability to define Context and Entity namespaces, and rename the context object via designer properties. So I had decided on Linq2Sql.

    Third, unit testing never really clicked with me. I understand the mechanics, just not able to properly envision what things I need to test, why I need to test them, what I am looking for, or how to read the result. It just flat never made much sense to me.

    Fourth, I am actually considering dropping injection altogether since I am not testing. I am not entirely sure I even need to use interfaces for most things at this point. Since I am not testing, there doesn't seem to be a point to either one.

    If you feel you can explain unit testing to me, in a way that I can understand, please do. Maybe I'll reconsider my stance, but as it stands right now. I simply think many of the mvc people out there are taking things way to much to heart, and are going way overboard...

  8. #8
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    TAKE TWO!

    After much hesitation and doubt, and the advice of numerous people over the past year, I've returned to the ddd version of my app and have made a lot of progress. However, I do have some things that concern me. I will try and express those concerns here in hopes that one of you will have an answer for me.

    1) Entity Traversal

    In a typical ddd application one entity may own one or more of another type of entity. New owned entities are added to the owning entity and then the owning entity is then saved.

    Code Csharp:
    Foo parent = fooRepository.SelectById(42);
    Bar child = new Bar("something_unique");
    parent.AddBar(child);
    fooRepository.Update(parent);

    Ok, this is fine, but what is happening in my application is when a self referencing entity adds children, and then those children have children, and so on for several generations.

    If somebody is viewing the details of such an entity four generations deep (for example), and that entity has no back referencing, how am I expected to build a navigation bar like the one at the top of this very page?

    SitePoint Forums > Forum Index > Program Your Site > .NET > Need MVC expert to verify I am on right track.

    Consider this following action of the forum controller:

    Code Csharp:
    public ActionResult View(int id)
    {
    Forum entity = forumRepository.SelectById(id);
    return View(Mapper.Map<Forum, ForumViewModel>(entity));
    }

    Without back referencing, I have no way for the view to build a navbar (via HtmlExtension method).

    2) ViewModel Missmatch

    In some cases, I require a confirmation before an action will proceed. Deletions are such a case. Here is an example:

    Code Csharp:
    public class ForumDeleteModel
    {
    public int Id { get; set; } // entity id
    public string Title { get; set; } // used to prompt user
    public bool Confirmed { get; set; } // user to get permission
    }
     
    [HttpPost, ValidateAntiForgeryToken]
    public ActionResult Delete(ForumDeleteModel model)
    {
    ConsumeErrors(validationService.Validate(model));
    if (!ModelState.IsValid) return View(model);
     
    // the rest is skipped secondary to explanation below
     
    }

    The problem in the above example is that the view only presents the user with a prompt like "Do you really want to delete forum named: {0}" where Title is formatted in. The model property Title is not however saved in a hidden field and is therefor not set upon post. If validation fails, and the model re-presented, there is no value for Title.

    I have two solutions here. One is to drop it onto the form in a hidden field, and that may make sense for this one form, but what about forms that display a great deal more temporary info? It doesn't seem logical to persist all that data in hidden fields. The second solution is to re-construct the model before sending it to the view. This also seems to be a little wrong, as I don't have to do it with other actions and models.

    I am not sure how to proceed with this.

    I am sure I will come up with more, but for now, this will do. Please advise.

  9. #9
    SitePoint Guru pufa's Avatar
    Join Date
    Oct 2004
    Location
    Portugal, Lisboa
    Posts
    947
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ciao, Rui...

  10. #10
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    Thanks pufa, but I already know how to recurse a tree from a root entity. That's not what I'm trying to do. I have the tip of a branch and need to recurse backwards, to the root, in order to build a navbar.

    Using my example above.

    SitePoint Forums > Forum Index > Program Your Site > .NET > Need MVC expert to verify I am on right track.

    What have is the Need MVC expert to verify I am on right track. part and I need to build the rest, back to SitePoint Forums.

  11. #11
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    Actually, I just had an idea that appears to solve a great deal of my problems involving forward and backward traversal, while still maintaining domain integrity. I think I can make it work, but I'll need a little help adjusting the convention cs files. I am not sure the current one will work, and I don't understand them well enough to know exactly what to change. Anyway, on to my idea.

    In the preferred design, an entity maintains a list of children, exposing it as an IEnumerable, and provides some accessor methods for adding and removing from it. Such an entity provides no reference to, or foreign key to, another entity that may be it's own owner. This makes backward traversal impossible.

    Some may argue that backwards traversal isn't something one should be able to do in a domain design, and for the most part, I'd agree. However, the demands of my application dictate that I need this. So my proposal is doing an inversion of the standard.

    In my scenario, my entities would expose their child lists as an IEnumerable, as before, but provide NO accessor methods. These lists are for downward traversal only and cannot be changed. Such an entity would however, expose any parent references, as a protected set property. We now have traversal in both directions. The only other thing that needs to change is the constructors.

    Whereas before I might have had:

    Forum parent = forumRepository.SelectById(1);
    Forum child = new Forum("Old Discussions");
    parent.AddChild(child);
    forumRepository.Update(parent);

    I would now have:
    Forum child = new Forum(parent, "Old Discussions");
    forumRepository.Insert(child);

    So it's basically an inversion of the recommended way of doing things, but it is still very solid, while allowing me to do what I need.

    Now, here's the problem...

    While I understand that with this scenario, I need to add instance.Inverse() to my HasManyConvention now, I am not sure how to construct my ReferenceConvention. Nothing I do, seems to work.

    This is what it currently looks like:
    Code Csharp:
    using FluentNHibernate.Conventions;
    using FluentNHibernate.Conventions.Inspections;
    using FluentNHibernate.Conventions.Instances;
     
    namespace Venue.Persistence.Mapping.Conventions
    {
     
        public class ReferenceConvention : IReferenceConvention 
        {
     
            public void Apply(IManyToOneInstance instance)
            {
     
                instance.ForeignKey(instance.EntityType.Name + "Id");
                instance.Cascade.All();
     
            }
     
        }
     
    }

    There is also an issue with needing an override in one entity map, but I'll address that once this is correct.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •