如何在StructureMap DI和MVC 5中解析相同类型的多个实现

时间:2018-03-09 04:10:31

标签: c# asp.net-mvc dependency-injection structuremap

我有一个由4类实现的接口。在我的公司控制器类构造函数中,我注入它。

以下是我的代码:

public static class IoC
{
    public static IContainer Initialize()
    {
        return new Container(c => c.AddRegistry<DefaultRegistry>());
    }
}

public class DefaultRegistry : Registry
{
    #region Constructors and Destructors
    public DefaultRegistry()
    {
        Scan(
            scan =>
            {
               scan.TheCallingAssembly();
               scan.WithDefaultConventions();
               // scan.AddAllTypesOf<ICompanyRepository>();
               scan.With(new ControllerConvention());
            });
        For<ICompanyRepository>().Add<CompanyRepository1>().Named("comRep1");
        For<ICompanyRepository>().Add<CompanyRepository2>().Named("comRep2");
        For<ICompanyRepository>().Add<CompanyRepository3>().Named("comRep3");
    }
    #endregion
}

现在在我的StructureMap代码

=============================================== ===

public class CompanyController : Controller
{
    readonly ICompanyRepository _companyRepository1;
    readonly ICompanyRepository _companyRepository2;
    readonly ICompanyRepository _companyRepository3;
    public CompanyController(ICompanyRepository comRep1,ICompanyRepository comRep2, ICompanyRepository comRep3)
    {
        _companyRepository1 = comRep1;
        _companyRepository2 = comRep2;
        _companyRepository2 = comRep3;
    }
}

=============================================== ===

在Customer控制器类中,我定义如下:

For<ICompanyRepository>().Add<CompanyRepository1>().Named("comRep1");
For<ICompanyRepository>().Add<CompanyRepository2>().Named("comRep2");
......
For<ICompanyRepository>().Add<CompanyRepository3>().Named("comRep10");

=============================================== =========

现在默认情况下它只加载来自comRep1的所有三个数据(comRep1,comRep2,comRep3)

这里有什么我想念的吗?

还有一个问题:我的界面是由10个类实现的,所以我应该像下面那样指定所有10个类和命名实例吗?

{{1}}

1 个答案:

答案 0 :(得分:1)

解决此问题的典型方法是创建通用存储库。通用存储库使您不必为每个实体反复重写相同的CRUD代码。

通用存储库

public interface IRepository<TEntity>
    where TEntity : class
{
    IEnumerable<TEntity> GetAll();
    TEntity Get(int id);
    TEntity Add(TEntity item);
    bool Update(TEntity item);
    bool Delete(int id);
}

public class Repository<TEntity> : IRepository<TEntity>
    where TEntity : class
{
    // Implement all the methods of the interface 
}

使用示例

然后,您可以使用泛型来轻松选择服务中的一个存储库(尽管它们都使用相同的类)。不需要使用命名实例,因为它们是基于泛型类型键入的。

class Program
{
    static void Main(string[] args)
    {
        var container = new Container(c =>
        {
            c.For<IService>().Use<Service>();
            // Register the generic repository for any entity
            c.For(typeof(IRepository<>)).Use(typeof(Repository<>));
        });

        // Resolve the service
        var service = container.GetInstance<IService>();
    }
}

public class Company { }
public class Employee { }
public class Timecard { }

public interface IService { }
public class Service : IService
{
    public Service(
        IRepository<Company> companyRepo, 
        IRepository<Employee> employeeRepo, 
        IRepository<Timecard> timecardRepo)
    {
        // All 3 repositories injected here
    }
}