Is the solution design optimal? C# 3 - Tier I have the following solution structure. This is a business domain (for an amount transfer operation in bank account) which will be called by a WCF service. Is the solution structuring correct? 


Data Acess Layer does not create domain objects. It just pass database record wrapped in another simple object (DataEntities.AccountRow). Is it a good/standard approach?
Manager and domain objects are in two different layers. Is it okay?
A layer “DTOforServiceCommunication” is created for communicating with WCF service. 
Is DTOforServiceCommunication and DataEntities are redundant or a good practice?
What are the improvement points for this solution structure?


Note: The service mentioned above will be used by multiple business functions (clients). Since the SOA is not object oriented, we cannot pass business domain objects across the boundary.



// TransferDTO

namespace DTOforServiceCommunication
{
public class TransferDTO
{
    public int UserID { get; set; }
    public int FromAccounutNumber { get; set; }
    public int ToAccountNumber { get; set; }
    public int AmountToTransfer { get; set; }
}
}


// AccountRow

namespace DataEntities
{
public class AccountRow
{
    public int AccountNumber { get; set; }
    public string AccountType { get; set; }
    public int Duration { get; set; }
    public int DepositedAmount { get; set; }

}
}


// AccountManager

namespace BusinessManager
{
public class AccountManager
{
    public void TransferAmount(DTOforServiceCommunication.TransferDTO  transferDTO)
    {
        //DAL does not create domain objects. It just pass database record wrapped in another simple object
        DAL.AccountDAL accountDAL = new DAL.AccountDAL();
        DataEntities.AccountRow row = accountDAL.GetAcocunt(transferDTO.UserID, transferDTO.FromAccounutNumber);

        DomainObject.IBankAccount bankAccount = null;
        if (String.Equals(row.AccountType, "Savings"))
        {
            bankAccount = new DomainObject.SavingsAccount();
            bankAccount.UserID = transferDTO.UserID;
            bankAccount.AccountNumber = row.AccountNumber;
            bankAccount.AmountDeposited = row.DepositedAmount;

        }
        else
        {
                bankAccount = new DomainObject.FixedAccount();
                bankAccount.UserID = transferDTO.UserID;
                bankAccount.AccountNumber = row.AccountNumber;
                bankAccount.AmountDeposited = row.DepositedAmount;
        }

        bankAccount.Transfer(transferDTO.ToAccountNumber, transferDTO.AmountToTransfer);

    }

}
} 


//DAL

namespace DAL
{
//DAL does not create domain objects. It just pass database record wrapped in another simple object
public class AccountDAL
{

    List&lt;DataEntities.AccountRow&gt; dbRecords = new List&lt;DataEntities.AccountRow&gt;()
    {
        new DataEntities.AccountRow{AccountNumber=1,AccountType="Savings",Duration=6,DepositedAmount=50000},
        new DataEntities.AccountRow{AccountNumber=2,AccountType="Fixed",Duration=6,DepositedAmount=50000}
    };

    public DataEntities.AccountRow GetAcocunt(int userID, int accountNumber)
    {
        return dbRecords[0];
    }

}


    }

READING:


http://msdn.microsoft.com/en-us/magazine/dd569757.aspx
https://stackoverflow.com/questions/125453/implementation-example-for-repository-pattern-with-linq-to-sql-and-c-sharp
https://stackoverflow.com/questions/3175/repository-pattern-tutorial-in-c-sharp/1374420#1374420
https://stackoverflow.com/questions/151769/whats-the-common-way-for-oop-pattern-design-data-access
https://stackoverflow.com/questions/4198136/classic-ado-net-or-entity-framework-better-for-larger-scale-database-transaction
http://sourceforge.net/projects/vanilla-dal/
https://stackoverflow.com/questions/9474425/should-the-configuration-of-an-application-be-accessed-using-dal
Data Acess Layer does not create domain objects. It just pass database record wrapped in another simple object (DataEntities.AccountRow). Is it a good/standard approach?


Repository classes should create domain objects. The domain objects may or may not look the same as the DB entities. 

If you mean that you write your DAL by yourself (and not using a ORM): Stop with that. It's a waste of time. 


  Manager and domain objects are in two different layers. Is it okay?


Use the term WCF service and not manager. Yes. I consider WCF services to be an UI layer since it's the interface to the calling user/client.


  A layer “DTOforServiceCommunication” is created for communicating with WCF service.


The name doesn't matter as long as you understand the difference between a domain object and a DTO.


  Is DTOforServiceCommunication and DataEntities are redundant or a good practice?


Good practice. The DTO's should never change since it would break all clients that use them.


  What are the improvement points for this solution structure?


No need for a userId in the WCF interfaces or the DTOs unless you want to let everyone be able to look at everybody elses accounts. Use the userid provided during authentication.

Update

Repository class using vanilla ADO.NET:

public class AccountRepository
{
    Dictionary&lt;string, Type&gt; _accountClasses = new Dictionary&lt;string, Type&gt;{{"savings", typeof(SavingsAccount)}, {"fixed", typeof(FixedAccount)}};
    List&lt;DataEntities.AccountRow&gt; dbRecords = new List&lt;DataEntities.AccountRow&gt;()
    {
        new DataEntities.AccountRow{AccountNumber=1,AccountType="Savings",Duration=6,DepositedAmount=50000},
        new DataEntities.AccountRow{AccountNumber=2,AccountType="Fixed",Duration=6,DepositedAmount=50000}
    };

    public T Get&lt;T&gt;(int userID, int accountNumber) where T : Account
    {
        var sql = "blabla";
        using (var cmd = _connection.CreateCommand())
        {
            cmd.CommandText = sql;
            using (var reader = cmd.ExecuteReader())
            {
                if (!reader.Read())
                    return null;

                var account = CreateRow(reader);
                if (account.GetType() != typeof(T));
                    throw new InvalidOperationException("The requested account was not of the specified type");

                return account;
            }
        }
    }

    public IEnumerable&lt;Account&gt; FindMyAccounts(int userId)
    {
        var sql = "blabla";
        using (var cmd = _connection.CreateCommand())
        {
            cmd.CommandText = sql;
            using (var reader = cmd.ExecuteReader())
            {
                List&lt;Account&gt; accounts = new List&lt;Account&gt;();
                while (reader.Read())
                {
                    var account = CreateRow(reader);
                    accounts.Add(account);
                }

                return accounts;
            }
        }
    }        

    // IDataRecord = a row in a DataReader
    public Account CreateRow(IDataRecord record)
    {
        // might want to check so that the account got a 
        Type type;
        if (!_accountClasses.TryGetValue(record["AccountType"], out type))
            throw new InvalidOperationExcpetion("Account type do not exist: " + record["AccountType"]);

        var account = (Account)Activator.CreateInstance(record);

        // fill record here
    }

}

public class Account
{
}

public class SavingsAccount : Account
{
}

public class FixedAccount : Account
{
}


Usage:

account = _repository.Get&lt;SavingsAccount&gt;(1, "kdkdkdkdkd");


Update2

Added a Find method to show that the actual mapping is reused by all methods. 

The Find method will also return different types of accounts in the same list.

You could also break out the ExecuteReader parts into two methods (one to fetch one item and one to fetch collections) to reuse the code more.