I am trying to build a multilayer application (service) in C#. To be precise, I am trying to build a REST webservice with ASP.NET Web Api which will be hosted on my own (with Owin). Now I got so far that I have the following components(every one of them is in a separate .dll):
- RestHost (which in my case is an console application)
- RestService (here is my web service witch all the controllers)
- InterfacesLayer
- ModelLayer (here are the objects I use, just with their get/set methods)
- DataLayer (every single class inside of ModelLayer has its own class in Datalayer, plus there is the Database connection class)
- BusinessLayer (here all the logic is done, again every class from model has its own class, and this layer communicates with the REST service and the datalayer).
RestHost - as the name says, it is the host of my service. Besides that I am also doing my dependency injection here. Since it is not much code I will post it:
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
// Dependency Resolving
container.RegisterType<IAktData, AktDataImpl>(new HierarchicalLifetimeManager());
container.RegisterType<IAktService, AktServiceImpl>(new HierarchicalLifetimeManager());
container.RegisterType<ILeistungData, LeistungDataImpl>(new HierarchicalLifetimeManager());
container.RegisterType<ILeistungService, LeistungServiceImpl>(new HierarchicalLifetimeManager());
container.RegisterType<IPersonData, PersonDataImpl>(new HierarchicalLifetimeManager());
container.RegisterType<IPersonService, PersonServiceImpl>(new HierarchicalLifetimeManager());
container.RegisterType<IPersistent, FirebirdDB>(new HierarchicalLifetimeManager());
string serverAddress = ConfigurationManager.AppSettings["serverAddress"];
string connectionString = ConfigurationManager.ConnectionStrings["connectionStrings"].ConnectionString;
using (RESTService.StartServer(container, serverAddress,connectionString ))
{
Console.WriteLine("Server started @ "+ DateTime.Now.ToString() + " on " + serverAddress + "/api");
Console.ReadLine();
}
}
Oh and what I forgot to mention, but you can see it from the code, in my host application I am also reading the App.Config where my connection string is hosted.
And here is my problem. I am not sure how to access the Database Connection from my service. Here I am implementing Firebird in my data access layer, but I am unsure how to use it in my application. Of course the easiest way would be just to create an instance and pass it to my service but this is the last thing i want to do. I have also been thinking implementing Firebird as a static class or as a singleton, but then i cannot use my IPersistant interface (and besides that, i don't think that this is the right approach).
So my question would be, is there any best practice for this kind of stuff? I somehow need to pass the connectionstring to the implementation of IPersistent (Firebird) but without actually creating an instance of Firebird in my RESTService.
Thanks
The general pattern for a multi-layer application like the one you're building is to have a data layer that provides your services with access to a database, or some other method of persisting data, usually via a repository.
You can then configure your IoC container to inject your connection string into your repository and then inject your repository into your service. This way your service stays agnostic as to how data is persisted and can focus on defining the business logic.
I actually do a similar thing for a repository that instead of persisting data in a database, stores it in a blob on Azure's CDN. The configuration withing my IoC (StructureMap in my case) looks like this:
string storageApiKey = ConfigurationManager.AppSettings["CloudStorageApiKey"];
string storageUsername = ConfigurationManager.AppSettings["CloudStorageUsername"];
this.For<IImageStorageRepository>().Use<ImageStorageRepository>().Ctor<string>("storageApiKey").Is(storageApiKey).Ctor<string>("storageUsername").Is(storageUsername);
With my repository looking like this:
public class ImageStorageRepository : IImageStorageRepository
{
....
public ImageStorageRepository(string storageApiKey, string storageUsername)
{
this.cloudIdentity = new CloudIdentity() { APIKey = storageApiKey, Username = storageUsername };
this.cloudFilesProvider = new CloudFilesProvider(cloudIdentity);
}
....
}