tags:

views:

164

answers:

4

Once upon a time I had a little .net project called Intranet. It simply served up web pages, and displayed some data retrieved from a database. Over time a monster has grown out of this little .net project. I've added different dashboards and reporting functionality and whatever else was requested of me at the time. Now I have a big .net project with too much going on in the one dll to effectively and quickly respond to management requests.

For example, If I need to make a quick change to some functionality in one logical area of the site and I'm in the middle of writing a larger piece of functionality for another part of the website I'm stuck with my intranet.dll not compiling. I know I could branch my source control but what I'd like to do is have multiple dlls. I'd like to have one per logical area of functionality.

How can I do this? Is it a manual process of creating each project and copying in the code? I'd like to have only one web.config for the whole thing. I would also like to be able to use the same membership provider handle all of the projects. What considerations do I need to make on the web server?

Any suggestions on how others deal with this sort of thing would be very helpful.

Thanks everyone.

+2  A: 

try adding some class library projects to your solution and move your codes to libraries...

Ozan BAYRAM
+3  A: 

You can start re-designing to upscale your project with more maintainable architecture. And of course this will take time and effort but eventually you'll have great results.

This is what I have in my project.

1.) Application.Infrastructure

  • Base classes for all businessobjects, busines object collection, data-access classes and my custom attributes and utilities as extension methods, Generic validation framework. This determines overall behavior organization of my final .net application.

2.) Application.DataModel

  • Typed Dataset for the Database.
  • TableAdapters extended to incorporate Transactions and other features I may need.

3.) Application.DataAccess

  • Data access classes.
  • Actual place where Database actions are queried using underlying Typed Dataset.

4.) Application.DomainObjects

  • Business objects and Business object collections.
  • Enums.

5.) Application.BusinessLayer

  • Provides manager classes accessible from Presentation layer.
  • HttpHandlers.
  • My own Page base class.
  • More things go here..

6.) Application.WebClient or Application.WindowsClient

  • My presentation layer
  • Takes references from Application.BusinessLayer and Application.BusinessObjects.

Application.BusinessObjects are used across the application and they travel across all layers whenever neeeded [except Application.DataModel and Application.Infrastructure]

All my queries are defined only Application.DataModel.

Application.DataAccess returns or takes Business objects as part of any data-access operation. Business objects are created with the help of reflection attributes. Each business object is marked with an attribute mapping to target table in database and properties within the business object are marked with attributes mapping to target coloumn in respective data-base table.

My validation framework lets me validate each field with the help of designated ValidationAttribute.

My framrwork heavily uses Attributes to automate most of the tedious tasks like mapping and validation. I can also new feature as new aspect in the framework.

A sample business object would look like this in my application.

User.cs

[TableMapping("Users")]
public class User : EntityBase
{
    #region Constructor(s)
    public AppUser()
    {
        BookCollection = new BookCollection();
    }
    #endregion

    #region Properties

    #region Default Properties - Direct Field Mapping using DataFieldMappingAttribute

    private System.Int32 _UserId;

    private System.String _FirstName;
    private System.String _LastName;
    private System.String _UserName;
    private System.Boolean _IsActive;

    [DataFieldMapping("UserID")]
    [DataObjectFieldAttribute(true, true, false)]
    [NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
    public override int Id
    {
        get
        {
            return _UserId;
        }
        set
        {
            _UserId = value;
        }
    }

    [DataFieldMapping("UserName")]
    [Searchable]
    [NotNullOrEmpty(Message = "Username Is Required.")]
    public string UserName
    {
        get
        {
            return _UserName;
        }
        set
        {
            _UserName = value;
        }
    }

    [DataFieldMapping("FirstName")]
    [Searchable]
    public string FirstName
    {
        get
        {
            return _FirstName;
        }
        set
        {
            _FirstName = value;
        }
    }

    [DataFieldMapping("LastName")]
    [Searchable]
    public string LastName
    {
        get
        {
            return _LastName;
        }
        set
        {
            _LastName = value;
        }
    }

    [DataFieldMapping("IsActive")]
    public bool IsActive
    {
        get
        {
            return _IsActive;
        }
        set
        {
            _IsActive = value;
        }
    }

    #region One-To-Many Mappings
    public BookCollection Books { get; set; }

    #endregion

    #region Derived Properties
    public string FullName { get { return this.FirstName + " " + this.LastName; } }

    #endregion

    #endregion

    public override bool Validate()
    {
        bool baseValid = base.Validate();
        bool localValid = Books.Validate();
        return baseValid && localValid;
    }
}

BookCollection.cs

/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection()
    {
    }

    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection (IList<Book> initialList)
        : base(initialList)
    {
    }
}
this. __curious_geek
If only I could get them to halt all new development for the next 3 weeks or so. But, this is going to work. I can have a main project that uses all my functional areas broken down into their own class library's. It shouldn't be too painful to accomplish at least that.
jim
Well if don't have time to sort your .dlls then why don't you branch the code?!?!?
Quibblesome
+2  A: 

It sounds like you have two problems here:

  1. Poor overall design, so all the code is lumped in together.
  2. No use of branching in your source control provider.

Simply splitting the code out (while useful), will not solve the problem of having breaking changes for fixes during new development. You need to also look at a modern SCM (i.e. not VSS) and start branching your code - it makes a massive difference.

Paddy
+1  A: 

You defiantly want to look into branching as even if your code is split up nicely you will still effectively have the same problem.

We operate off 3 branches Dev, Test, Release all new features going into dev. When we are happy with them that they work and are ready for test they go to test and when they have been tested they can go to release which is the environment that goes to the customer/gets deployed.

There is nothing stopping us doing quick fixes in Test and merging them back into dev then release.

I would suggest you look at this it is called the code promotion model of source control.

Burt