Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6634997
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T22:59:48+00:00 2026-05-25T22:59:48+00:00

When designing an n-tier application, I tend to use a pattern adopted and adapted

  • 0

When designing an n-tier application, I tend to use a pattern adopted and adapted from Lhotka’s CSLA framwork. In a nutshell, the Repository layer populates a SqlDataReader and passes the data reader, the instance to be mapped, and the mapping information to the Mapper layer which then populates the instance.

This pattern has proved itself over and again in many projects I have worked on for a number of reasons:

  1. It is easy to understand and implement, developers tend to stick to it because they understand what it is doing.
  2. It enables very easy reuse of the mappers for inherited classes and well as composite classes.
  3. Any changes in the entity, and therefore the mapper assigned to it, cause compile time errors pointing directly to the stored procs that also need to be changed.

Here is some sample repository code:

internal static List<CompositeEntities.ContactReportRpa> RetrieveByReportId(int reportId)
{
  CompositeEntities.ContactReportRpa report = null;
  List<CompositeEntities.ContactReportRpa> reports = new List<CompositeEntities.ContactReportRpa>();
  using (SqlConnection conn = DBConnection.GetConnection())
  {
    cmd.Connection = conn;
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.CommandText = "ContactReportRpa_SEL_ByIdReport";
    cmd.Parameters.Add("@IdReport", System.Data.SqlDbType.Int).Value = reportId;
    conn.Open();
    using (SqlDataReader reader = cmd.ExecuteReader())
    {
     while (reader.Read())
     {
       report = new CompositeEntities.ContactReportRpa();
       ContactReportRpaMapper.Map("IdReportRpa", "IdReport", "IdRecommendation", "IsDisplayed", "Comments", report.Rpa, reader);
       RpaRecommendationMapper.Map("IdRecommendation", "IdDepartment", "TitleRecommendation", "Description", "DisplayOrderRecommendation", report.Recommendation, reader);
       RpaDepartmentMapper.Map("IdDepartment", "TitleDepartment", "DisplayOrderDepartment", report.Department, reader);
       reports.Add(report);
     }
    }
   }
   return reports;
 }

Here is some sample Mapper Code. It is pretty straightforward: The mapper knows which class property gets mapped to each field in the data reader. The name of each field is passed to the mapper so the same mapper can be used regardless of the names assigned to each field in the sproc.

internal static void Map(string fieldId, string fieldName, string fieldDisplayOrder,   RpaDepartment entity, SqlDataReader reader)
{
  entity.Id = reader.GetInt32(reader.GetOrdinal(fieldId));
  entity.Title = reader.GetString(reader.GetOrdinal(fieldName));
  entity.DisplayOrder = reader.GetInt32(reader.GetOrdinal(fieldDisplayOrder));
}

So my question is this: How should I implement this pattern when the data source is a text file? I want to stick with this pattern because eventually the data source will be migrated to a db.

Any suggestions?

EDIT: The ini files already exist and I do not have the go ahead to change them at this time. So I am stuck with them for now.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T22:59:49+00:00Added an answer on May 25, 2026 at 10:59 pm

    It is a bit difficult to create a good data hierarchy in ini files. This is part of why MS seems to have migrated mostly to XML files. See the answer to this question: Reading/writing an INI file

    If you go with the XML option, I’d skip this mapping stuff and simply serialize your objects directly in after using XPath to find the appropriate XML. Then you don’t need a mapper.

    You could also go with an in-memory or file-based DB, like SqLite. Perf will be great, and you will have a very small deployment footprint.

    Also, I recommend avoiding trying to abstract this mapper stuff, since I don’t think it will translate well between a DB and an ini file. If you look at the complexity of the many ORM libraries out there, you will see how difficult this mapping really can be. Most of the concepts at the mapping level simply don’t translate well to an ini file. It is the higher level concepts that will map (repositories), which is why I posted my original answer (see below).

    But if you want to keep with the pattern you’re using, and your ini file looks something like this:

    [Report.3]
    IdReport = 3
    IdReportRpas = 7,13
    
    [ReportRpa.7]
    IdReportRpa = 7
    IdReport = 3
    IdRecommendation = 12
    IsDisplayed = true
    Comments = I'm not sure what an RPA is...
    
    [ReportRpa.13]
    IdReportRpa = 13
    IdReport = 3
    ; ... and rest of properties here
    
    [Recommendation.12]
    IdRecommendation = 12
    IdDepartment = 33
    TitleRecommendation = Some Recommendation
    Description = Some Recommendation Description
    DisplayOrderRecommendation = 0
    
    [Department.33]
    IdDepartment = 33
    TitleDepartment = Bureau of DBs and ini files
    DisplayOrderDepartment = 0
    

    … then you could simply write your repository to grab data out of ini sections, and write your mappers to look at each ini value the same way you are currently looking at columns in your result set.

    using(var iniFileReader = new IniFileReader())
    {
        string reportSectionName = string.Format("Report.{0}", contactId);
        var reportSection = iniFileReader.GetSection(reportSectionName);
    
        // Todo: Abstract this sort of procedure/enumeration stuff out.
        // Similar to the existing code's stored procedure call
        int[] idReportRpas = reportSection.GetValue(IdReportRpas)
            .Split(',')
            .Select(s => int.Parse(s);
    
        foreach(string idReportRpa in idReportRpas)
        {
            report = new CompositeEntities.ContactReportRpa();
    
            string rpaSectionName = string.Format("ReportRpa.{0}", idReportRpa);
            var rpaSection = iniFileReader.GetSection(rpaSectionName);
    
            ContactReportRpaMapper.Map("IdReportRpa", "IdReport", "IdRecommendation",
                "IsDisplayed", "Comments", report.Rpa, rpaSection);
    
            // ...
        }
    }
    

    Your current mapper code is bound to your storage type, so you’ll need to come up with a more generic mapper interface. Or make that last reader parameter more generic to support both mapping types (in your case, reader, in my case, each ini section instance). E.g.:

    public interface IDataValueReader
    {
        // Signature is one that might be able to support ini files:
        // string -> string; then cast
        //
        // As well as a DB reader:
        // string -> strongly typed object
        T ReadValue<T>(string valueName);
    }
    
    public class DbDataReader : IDataValueReader
    {
        private readonly SqlDataReader reader;
    
        public DbDataReader(SqlDataReader reader)
        {
            this.reader = reader;
        }
    
        object ReadValue<T>(string fieldId)
        {
            return (T)reader.GetObject(reader.GetOrdinal(fieldId));
        }
    }
    
    public class IniDataSectionReader : IDataValueReader
    {
        private readonly IniFileSection fileSection;
    
        public IniDataSectionReader(IniFileSection fileSection)
        {
            this.fileSection = fileSection;
        }
    
        object ReadValue<T>(string valueName)
        {
            return (T)Convert.ChangeType(fileSection.GetValue(fieldId), typeof(T));
        }
    }
    

    Note that this is all custom code – there is no official ini file reader, and I haven’t tried any out so I can’t make a suggestion on which third party library to use. That question I linked at the top has some recommendations.

    Original answer

    (part of it may still be useful)

    Make an interface for your repository, and make sure the higher level layers of your code only talk to your data store through this interface.

    An example interface (yours might be different):

    public interface IReportRepository
    {
        void Create(Report report);
        Report Read(int id);
        void Update(Report report);
        void Delete(Report report);
    }
    

    You could also make this interface generic, if you wanted.

    To make sure the higher level layers only know about the repository, you could construct the classes for talking to the file/DB in the implementation of IReportRepository, or use Dependency Injection to populate it. But whatever you do, don’t let your higher level code know about anything but IRepository and your individual data entities (Report).

    You might also want to look into the Unit of Work pattern, and wrap the actual data access there. That way you can easily support transactional semantics, and buffered/lazy storage access (even with a file).

    For your example implementation, the SqlConnection and SqlDataReader would live in your unit of work class, and the mapping code and specific stored procedure names would probably live in each repository class.

    It might be a bit tricky to get this structure to work completely independently, but if you look at the code the Microsoft Entity Framework generates, they actually have their unit of work class instantiate each repository, and you just access it like a property. Something roughly like:

    public interface IUnitOfWork : IDisposable
    {
        void CommitChanges();
        void RollbackChanges();
    }
    
    public class MyDataModel : IUnitOfWork
    {
        private bool isDisposed;
        private readonly SqlConnection sqlConnection;
    
        public MyDataModel()
        {
            sqlConnection = DBConnection.GetConnection();
        }
    
        // Todo: Implement IUnitOfWork here
    
        public void Dispose()
        {
            sqlConnection.Dispose();
            isDisposed = true;
        }
    
        public IRepository<Report> Reports
        {
            get
            {
                return new ReportDbRepository(sqlConnection);
            }
        }
    }
    
    public class ReportDbRepository : IRepository<Report>
    {
        private readonly SqlConnection sqlConnection;
    
        public ReportDbRepository(SqlConnection sqlConnection)
        {
            this.sqlConnection = sqlConnection;
        }
    
        // Todo: Implement IRepository<Report> here using sqlConnection
    }
    

    Useful reading:

    • Repository pattern reference
    • Dependency Injection
    • Unit of Work pattern
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm in a process of designing a multi-tier ASP.NET web application that is supposed
While designing a new WPF application I noticed exceptions not being thrown during data
When designing an distributed application in Java there seem to be a few technologies
Thanks for taking time to read this question. I am designing a 3-tier solution
When designing a client/server architecture, is there any advantage to multiplexing multiple connections from
I'm designing a C# application Presentation ( web site + flex apps ) Business
Im designing my first android application and keep coming up with the following error
When designing an application with a large number of remote services, is it better
I need your suggestions in designing a Java/J2EE web based application. Here are its
I am designing the architecture of a new web site. Since multi-tier architecture definitely

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.