StructureMap和多层MVC解决方案

本文关键字:MVC 解决方案 StructureMap | 更新日期: 2023-09-27 18:25:29

我有一个这样的项目结构:数据层-适用于模型MVC网站-适用于所有其他与MVC网站相关的网站。

我希望我的控制器同时注入数据库上下文和服务,并且仍然确保依赖注入。

这是我的代码我的控制器:

  private CMSDB _db;
    public HomeController(CMSDB db)
    {
        _db = db;
    }

我的数据库上下文

  public class CMSDB : DbContext
{
    public CMSDB() : base("DefaultConnection"){   }
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Departments { get; set; }
    public DbSet<UserDatails> Users { get; set; }
    public DbSet<UserRole> UserRoles { get; set; }
    public DbSet<Module> Modules { get; set; }
}

单独项目中的模型

 public class Module : IModule
{
   public virtual int ID { get; set; }
   public virtual string Name { get; set; }
   public virtual DateTime? DateCreated { get; set; }
   public virtual string ModuleDescription { get; set; }
} 

我与型号在同一项目中的界面

 public interface IModule
 {    }

我希望我的控制器同时注入CMSDB和IModule,并且仍然确保依赖注入。

重要的因素是以后能够从中分解出任何其他解决方案(可能是门户)。欢迎所有意见。

StructureMap和多层MVC解决方案

确保您正在创建映射,该映射应在启动时运行

   public static class ContainerBootstrapper
    {
        public static void BootstrapStructureMap()
        {
            // Initialize the static ObjectFactory container
            ObjectFactory.Initialize(x =>
            {
                x.ForRequestedType<iNTERFACE>().TheDefaultIsConcreteType<ContreteClass>();
            });
        }
    }

然后

  iNTERFACE objectINMVCController = ObjectFactory.GetInstance<iNTERFACE>();

虽然标记为正确答案的答案会起作用,因为这个特定的问题与StructureMap 3有关,但值得一提的是,不建议使用StructureMap的ObjectFactory,而且在版本4中实际上已被弃用(当您尝试构建解决方案时,您无疑会看到这一点)。

相反,更好的选择是使用StructureMap的IContainer接口,通过以下解决方案组成依赖项:

var container = new Container(x => {
    x.For<IInterface>().Use<ConcreteClass>();
    x.For<IInterface2>().Use<ConcreteClass2>();
}); 

当你特别提到可重用性时,我建议你看看StructureMap的注册表类,它们允许你在注册表中封装依赖项,比如:

public class WebsiteRegistry : Registry
{
    public WebsiteRegistry()
    {
        For<ICustomerService>().Use<CustomerService>();
        For<IProductServer>().Use<ProductService>();
    }
}

然后,您可以通过类似的方式组成和注册您的注册表类:

IContainer container = new Container(x =>
{
    x.AddRegistry<DatabaseRegistry>();
    x.AddRegistry<WebsiteRegistry>();
});

这样做的好处是可以将注册表类分解为核心依赖项、基于网站的依赖项和web服务依赖项。例如,您的网站和web服务都需要数据库访问,因此可以进入核心注册表,但您的网站可能需要SessionRegistry,这在web服务中是无用的(由于web服务的无会话性质)。

然后,您只需在Global.asax.cs类中使用ASP.NET MVC的依赖解析程序注册StructureMap。