Intro: - I am new to programming and I have used constructor injection and the factory pattern a lot. This will be my first time using a third party tool, Autofac, for DI. I understand the basics but I'm looking for understanding on a few things and I hope you can help.
Project Setup: N-Tier MVC Application (Data, Models, Tests, UI projects)(NuGet Autofac and Autofac.MVC5 installed only in UI project)
Question: Should Autofac be installed via NuGet in every project within my N-Tier MVC application or is just having it in the UI project okay? I am experimenting with Modules and curious if my DataAccessModule should be placed in my Data project vs the UI project.
Multi-Part Question: I'm trying to inject the connection string into my repository and I'm not sure if I'm doing this correctly. The repositories get registered based on what value for RepositoryType is set in my Web.config file. I am using ADO and stored procedures in my example. Reading about Autofac.Module, I thought this would be the way to go.
AutofacConfig
public static class AutofacConfig
{
public static void RegisterComponents()
{
//Autofac - install Autofac and Autofac.MVC5 via NuGet
//Autofac: create the builder with which components/services are registered.
var builder = new ContainerBuilder();
//register all the components that we will use in our container
//register HomeController as I only have one
builder.RegisterType<HomeController>().InstancePerRequest();
//register DataAccessModule
builder.RegisterModule(new DataAccessModule
{
ConnectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString,
RepositoryType = ConfigurationManager.AppSettings["RepositoryType"].ToString()
});
//builds our container
var container = builder.Build();
//let ASP.NET MVC know that it should locate services using the AutofacDependencyResolver. This is Autofac’s implementation of the IDependencyResolver interface.
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
DataAccessModule
public class DataAccessModule : Module
{
public string ConnectionString { get; set; }
public string RepositoryType { get; set; }
protected override void Load(ContainerBuilder builder)
{
switch (RepositoryType)
{
case "ADO":
builder.RegisterType<DirectorRepositoryADO>().As<IDirectorRepository>().WithParameter("connectionString",ConnectionString).InstancePerRequest();
builder.RegisterType<DvdDirectorRepositoryADO>().As<IDvdDirectorRepository>().WithParameter("connectionString", ConnectionString).InstancePerRequest();
builder.RegisterType<DvdRepositoryADO>().As<IDvdRepository>().WithParameter("connectionString", ConnectionString).InstancePerRequest();
builder.RegisterType<RatingRepositoryADO>().As<IRatingRepository>().WithParameter("connectionString", ConnectionString).InstancePerRequest();
break;
}
}
}
Repository
public class RatingRepositoryADO : IRatingRepository
{
private readonly string _connectionString;
public RatingRepositoryADO(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<Rating> GetAll()
{
List<Rating> ratings = new List<Rating>();
using (var cn = new SqlConnection(_connectionString))
{
SqlCommand cmd = new SqlCommand("RatingSelectAll", cn);
cmd.CommandType = CommandType.StoredProcedure;
cn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
Rating currentRow = new Rating();
currentRow.RatingId = (byte)dr["RatingId"];
currentRow.RatingName = dr["RatingName"].ToString();
ratings.Add(currentRow);
}
}
}
return ratings;
}
}
- Am I way off on how I have implemented my Module and passing in the connection string?
- Should I separate my connection into a separate class that implements an interface with a method of GetConnectionString and resolve it and set the instance scope as a singleinstance instead of the way I have it?
- Should repositories use InstancePerRequest or InstancePerLifetimeScope? I've seen both in some examples so I just want to know what is best to use and why/when
Question: Anywhere I see the "new" keyword in my project should I try and inject that dependency? For example, in my repository, the SqlConnection or SqlCommand objects?
Any help or guidance you can provide would be greatly appreciated. I trying to perform a very basic example to better understand how I might configure other components
Thank you in advance!