locked
Configuring an independet data access layer RRS feed

  • Question

  • Hi, I'm developing a new layered application to send SMS messages.
    The application contains the web module, and assemblies for the data access, bussines logic and bussines object layer.
    The web module is not the unique client for the assemblies, so I wish I could deploy and use the assemblies independent from the web module.
    My question is how is the best way to configure the data access layer ? (for example connection strings) I thought about reading a xml file, there are problems with this approach, the location of the file to read for example; reading the registry seems a old way.

    Any tips ?
    Thanks for any help !
    Wednesday, July 25, 2007 1:26 PM

Answers

  •  LivetoCodeCodetoLive! wrote:

     

     Mike Chaliy wrote:

    I am arguing not to use this solution. It breaks DAL boundaries. Services other then master data services may not to expose CRUD operations. This is unpredictable behavior. Anybody can violate your business rules. Imagine you have Order table, you expose method UpdateOrder. You have Total column. Everybody can change your totals! This is definitely synthetic example, but I think you got idea. Instead if your service exposes method RecalcualteTotal, that will do all work on server side, you will not have such issues. Also with this solution you centralize your business logic. This means that if rules of calculateing are changed, you will not need to update your clients - just server code.

     

    I understand where Mike is coming from, but you can expose your dataservices to be used by other business services. Specifying  who can and can't use your service is another issue, but there are frameworks out there that create a DAL layer as a service even the ADO.NET team are doing this now http://blogs.msdn.com/adonet/archive/2007/04/30/project-codename-astoria-announced-at-mix-07.aspx

     

    But I totally agree that other applications should go through the business layer every time, just that doesn't mean you shouldn't create a data services layer.

     

    Saturday, July 28, 2007 1:18 AM

All replies

  • Dude,

    Definitely sounds like you should put the connection string in your Web.config file.

     

    Wednesday, July 25, 2007 5:29 PM
  • In some cases there's no web application, imagine the assembly being deployed on the GAC of an server. Could I still use a web.config file ?
    Thanks.
    Wednesday, July 25, 2007 6:33 PM
  • You can add an app.config file if the client application is a windows application or a class library. The app.config file is like and xml file that you can access from .net namespaces.

    Wednesday, July 25, 2007 7:25 PM
  • Personally I would look at using some kinda ORM tool for your data acess layer, most of these products have a defined method for storing connection string. Failing that if you aren't going to use an ORM tool I would consider looking spring.net framework, not only does this give dependency injection (inversion of control) it allows you to better manage configuration files for assemblies\applications etc.

     

    HTH

     

    Ollie Riches

     

    Thursday, July 26, 2007 12:31 PM
  •  Ollie Riches wrote:

    Personally I would look at using some kinda ORM tool for your data acess layer, most of these products have a defined method for storing connection string. Failing that if you aren't going to use an ORM tool I would consider looking spring.net framework, not only does this give dependency injection (inversion of control) it allows you to better manage configuration files for assemblies\applications etc.

     

    HTH

     

    Ollie Riches

     

     

    I totally agree about the ORM tool, but Spring.net might have performance implications that need to be taken into consideration.

     

     

    Thursday, July 26, 2007 12:40 PM
  • An approach could be write a "Configure" method receiving the connection string, decoupling the configuration source from the assembly itself.
    This way I have to configure the assembly parameters per application basis. Remembering one client application can be the web app, but the same assembly could be used from another assembly, a serviced component for example.
    Centralizing the configuration source inside the assembly (installed on the GAC for example) providing per machine configuration is the way I was thinking about.

    Thursday, July 26, 2007 6:48 PM
  •  Guima wrote:
    An approach could be write a "Configure" method receiving the connection string, decoupling the configuration source from the assembly itself.
    This way I have to configure the assembly parameters per application basis. Remembering one client application can be the web app, but the same assembly could be used from another assembly, a serviced component for example.
    Centralizing the configuration source inside the assembly (installed on the GAC for example) providing per machine configuration is the way I was thinking about.

     

    That would be ok, but then you would have to pas sthe connection string to the assembly each time you refernce the assembly. With the config files, the connection string is read from the config file of the assembley that will reference your DAL Layer.

     

     

    Friday, July 27, 2007 4:03 PM
  • Another approach I think you should alos consider would be to use WCF, you can have your DAL accessed as a WCF component, and you can specify the protocol you wish to access this service through the configuration files.

    For instance you could use a binary protocol inside the intranet for [erformance, and http on the outside.

    If you want to centralize configuration you should do that ona per service basis IMHO. Because it is the DAL that should be aware of the connection string and not the client application. If the connection string differs from one client to another then it should be in the configuration file of the client application and when you reference the DAL.

     

    I hope what i said makes some sense.

    Please provide me with your feedback.

    Friday, July 27, 2007 4:42 PM
  •  LivetoCodeCodetoLive! wrote:

    That would be ok, but then you would have to pas sthe connection string to the assembly each time you refernce the assembly. With the config files, the connection string is read from the config file of the assembley that will reference your DAL Layer.

    This is always good to implement things decoupled from configuration. With dependencies on config this is hard to configure testing environment, this is hard to reimplement configuration, etc. Factory method is likely better solution for this.

    Friday, July 27, 2007 6:04 PM
  •  LivetoCodeCodetoLive! wrote:

    Another approach I think you should alos consider would be to use WCF, you can have your DAL accessed as a WCF component, and you can specify the protocol you wish to access this service through the configuration files.

    For instance you could use a binary protocol inside the intranet for [erformance, and http on the outside.

    If you want to centralize configuration you should do that ona per service basis IMHO. Because it is the DAL that should be aware of the connection string and not the client application. If the connection string differs from one client to another then it should be in the configuration file of the client application and when you reference the DAL.

     

    I hope what i said makes some sense.

    Please provide me with your feedback.

     

    I am arguing not to use this solution. It breaks DAL boundaries. Services other then master data services may not to expose CRUD operations. This is unpredictable behavior. Anybody can violate your business rules. Imagine you have Order table, you expose method UpdateOrder. You have Total column. Everybody can change your totals! This is definitely synthetic example, but I think you got idea. Instead if your service exposes method RecalcualteTotal, that will do all work on server side, you will not have such issues. Also with this solution you centralize your business logic. This means that if rules of calculateing are changed, you will not need to update your clients - just server code.

    Friday, July 27, 2007 6:15 PM
  •  LivetoCodeCodetoLive! wrote:

     

     Mike Chaliy wrote:

    I am arguing not to use this solution. It breaks DAL boundaries. Services other then master data services may not to expose CRUD operations. This is unpredictable behavior. Anybody can violate your business rules. Imagine you have Order table, you expose method UpdateOrder. You have Total column. Everybody can change your totals! This is definitely synthetic example, but I think you got idea. Instead if your service exposes method RecalcualteTotal, that will do all work on server side, you will not have such issues. Also with this solution you centralize your business logic. This means that if rules of calculateing are changed, you will not need to update your clients - just server code.

     

    I understand where Mike is coming from, but you can expose your dataservices to be used by other business services. Specifying  who can and can't use your service is another issue, but there are frameworks out there that create a DAL layer as a service even the ADO.NET team are doing this now http://blogs.msdn.com/adonet/archive/2007/04/30/project-codename-astoria-announced-at-mix-07.aspx

     

    But I totally agree that other applications should go through the business layer every time, just that doesn't mean you shouldn't create a data services layer.

     

    Saturday, July 28, 2007 1:18 AM
  • Very good link, and you got my point, the assembly exposes a data service.

    Now I'm implementing a wrapper to the data class as a serviced component.
    I'm planning to use the constructor string from the serviced component wrapper to configure the data layer assembly, calling the Configure static method.
    This scenario may be very complicated if I wish to configure the assembly on the application layer, because the COM+ is stateless we can't determine the lifecycle of the instantiated object, so the connection string would be passed on every call. It would be very useful.

    I'm surprised that I can't find articles for this subject on the net, or what I wish to do is very unusual.

    Thanks again.


    EDIT:
    I think I find the solution I was looking for.

    Inside the DAL assembly I'll read the configuration settings using ConfigurationManager.ConnectionStrings.

    It'll work on web and windows contexts.

    On the COM+ context, the same code will work if I create an Application Root Directory to the Component package, and create a application.manifest file, and finally create an "application.config" with the same settings.

    At least in theory it'll work.

    Monday, July 30, 2007 6:53 PM
  •  Guima wrote:
    Very good link, and you got my point, the assembly exposes a data service.




    EDIT:
    I think I find the solution I was looking for.

    Inside the DAL assembly I'll read the configuration settings using ConfigurationManager.ConnectionStrings.

    It'll work on web and windows contexts.

    On the COM+ context, the same code will work if I create an Application Root Directory to the Component package, and create a application.manifest file, and finally create an "application.config" with the same settings.

    At least in theory it'll work.

     

    I agree with this solution, if I understand correctly, isn't this the solution I described above, or is there a difference?

    The idea of having the connection string in the client config file, and when you use "ConfigurationManager.ConnectionStrings", it will read the connection string from the config file if the referncing solution. Right?

    Monday, July 30, 2007 10:15 PM
  •  Guima wrote:

    Inside the DAL assembly I'll read the configuration settings using ConfigurationManager.ConnectionStrings.

     

    Hello Guima, why not to use factories?

     

    Lets create DAL class that will be configurable with connection string:

     

    Code Snippet

    public class CustomersAdapter

    {

    private string _connectionString;

    public CustomersAdapter(string connectionString)

    {

    if (String.IsNullOrEmpty(connectionString))

    {

    throw new ArgumentNullException("connectionString");

    }

    }

     

    public IEnumerable RetrieveCustomers()

    {

    using(DbConnection connection = this.CreateConnection()

    {

    ....

    }

    }

    }

     

 

 

Now with in specific application (e.g. Desktop, Web or COM+), you will need concrete factory that will retrieve its configuration from its specific configuration.

 

Code Snippet

public class CustomersAdapterFactory

{

pubic CustomersAdapter CreateCustomersAdapter()

{

string connectionString = ConfigurationManager.ConnectionStrings["Default"];

CustomersAdapter  adapter = new CustomersAdapter(connectionString );

return adapter;

}

}

 

 

 

 

This will decouple your DAL from concrete configuration implementation. This is proven pattern (DI or IoC). This is always better do not make direct dependencies on other modules (in our case this DAL and Configuration). Also this can be a good solution for your initial problem, because you will be able to share DAL across application but not implement tricks.

Wednesday, August 1, 2007 9:47 AM