下面是一个简单但实用的示例,大致说明了如何进行依赖项注入。当我的dbcontext连接字符串不是动态的时,这非常有用。即使它是通过配置文件或其他方式传递到工厂的,只要它一直是同一个就没关系。
我需要了解的是如何对下面的代码进行(最好是小的)修改,以便在运行时动态地确定连接字符串。
例如,假设在视图上,用户不仅可以选择要传递到控制器的post方法的教师,而且还可以选择学校。如果为了简单起见,有两个学校有完全相同的数据库结构,但有不同的连接字符串,我如何从控制器到工厂?
我曾尝试过将一个值从一个方法传递到另一个方法,但这对于大型项目来说并不是真正可持续的,它增加了出错的可能性,而且总的来说,像这样从一个层传递到另一个层只是一团乱(除了违反实体)。
(如果需要的话,我可以添加我所做的不太理想的尝试,为了简洁起见,我省略了它们,因为这已经是一个相当长的问题,代码示例和所有这些都是什么)。
控制器
public class HomeController : Controller
{
private readonly IDataService _dataService;
public HomeController(IDataService dataService)
{
_dataService = dataService;
}
public ActionResult Index()
{
var results = _dataService.GetTeachers();
var model = new ViewModel
{
Teachers = results
};
return View(model);
}
[HttpPost]
public ActionResult Index(ViewModel model)
{
var results = _dataService.GetCourses(model.Teacher);
model.Courses = new List<string>(results);
return View(model);
}
}
服务
public class DataService : IDataService
{
private readonly IDataRepo _dataRepo;
public DataService(IDataRepo dataRepo)
{
_dataRepo = dataRepo;
}
public List<string> GetCourses(string teacherName)
{
return _dataRepo.GetCourses()
.Where(c => c.Teacher.FirstName == teacherName)
.Select(c => c.Name)
.ToList();
}
public List<string> GetTeachers()
{
return _dataRepo.GetCourses()
.Select(c => c.Teacher.FirstName)
.ToList();
}
}
存储库
public class DataRepo : IDataRepo
{
private readonly SchoolContext _context;
public DataRepo()
{
_context = ContextFactory.MakeContext();
}
public IEnumerable<Course> GetCourses()
{
return _context.Courses;
}
}
上下文工厂
public static class ContextFactory
{
public static SchoolContext MakeContext()
{
var connString =
"connStringA";
return new SchoolContext(connString);
}
}
单位配置
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<IDataService, DataService>();
container.RegisterType<IDataRepo, DataRepo>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}