Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Autofac动态解析依赖项_C#_Dependency Injection_Asp.net Web Api2_Autofac_Ioc Container - Fatal编程技术网

C# 使用Autofac动态解析依赖项

C# 使用Autofac动态解析依赖项,c#,dependency-injection,asp.net-web-api2,autofac,ioc-container,C#,Dependency Injection,Asp.net Web Api2,Autofac,Ioc Container,像我现在这样动态地解决依赖关系好吗。在任何地方,都建议使用构造函数注入。我真的不明白我这样做的缺点。代码片段如下所示 Employee.cs public class Employee { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public Department Department { get; set; } } pub

像我现在这样动态地解决依赖关系好吗。在任何地方,都建议使用构造函数注入。我真的不明白我这样做的缺点。代码片段如下所示

Employee.cs

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public Department Department { get; set; }
}
public interface IRepository<TModel> where TModel : class
    {
        void Add();
        IEnumerable<TModel> GetAll();
        IEnumerable<TModel> GetByID();
    }
public class Repository<TModel> : IRepository<TModel> where TModel : class
{
    public void Add()
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TModel> GetAll()
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TModel> GetByID()
    {
        throw new NotImplementedException();
    }
}
public class HomeController : ApiController
{
    IComponentContext _container;

    public HomeController(IComponentContext container)
    {
        this._container = container;
    }

    public Repository<TModel> Using<TModel>() where TModel :class
    {
        var repository = _container.Resolve(typeof(IRepository<TModel>));
        return repository as Repository<TModel>;
    }

    [HttpGet]
    public IEnumerable<Employee> GetEmployees()
    {
        return Using<Employee>().GetAll();
    }
}
IRepository.cs

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public Department Department { get; set; }
}
public interface IRepository<TModel> where TModel : class
    {
        void Add();
        IEnumerable<TModel> GetAll();
        IEnumerable<TModel> GetByID();
    }
public class Repository<TModel> : IRepository<TModel> where TModel : class
{
    public void Add()
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TModel> GetAll()
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TModel> GetByID()
    {
        throw new NotImplementedException();
    }
}
public class HomeController : ApiController
{
    IComponentContext _container;

    public HomeController(IComponentContext container)
    {
        this._container = container;
    }

    public Repository<TModel> Using<TModel>() where TModel :class
    {
        var repository = _container.Resolve(typeof(IRepository<TModel>));
        return repository as Repository<TModel>;
    }

    [HttpGet]
    public IEnumerable<Employee> GetEmployees()
    {
        return Using<Employee>().GetAll();
    }
}
公共接口IRepository,其中TModel:class
{
无效添加();
IEnumerable GetAll();
IEnumerable GetByID();
}
Repository.cs

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public Department Department { get; set; }
}
public interface IRepository<TModel> where TModel : class
    {
        void Add();
        IEnumerable<TModel> GetAll();
        IEnumerable<TModel> GetByID();
    }
public class Repository<TModel> : IRepository<TModel> where TModel : class
{
    public void Add()
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TModel> GetAll()
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TModel> GetByID()
    {
        throw new NotImplementedException();
    }
}
public class HomeController : ApiController
{
    IComponentContext _container;

    public HomeController(IComponentContext container)
    {
        this._container = container;
    }

    public Repository<TModel> Using<TModel>() where TModel :class
    {
        var repository = _container.Resolve(typeof(IRepository<TModel>));
        return repository as Repository<TModel>;
    }

    [HttpGet]
    public IEnumerable<Employee> GetEmployees()
    {
        return Using<Employee>().GetAll();
    }
}
公共类存储库:IRepository,其中TModel:class
{
公共无效添加()
{
抛出新的NotImplementedException();
}
公共IEnumerable GetAll()
{
抛出新的NotImplementedException();
}
公共IEnumerable GetByID()
{
抛出新的NotImplementedException();
}
}
EmployeeController.cs

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public Department Department { get; set; }
}
public interface IRepository<TModel> where TModel : class
    {
        void Add();
        IEnumerable<TModel> GetAll();
        IEnumerable<TModel> GetByID();
    }
public class Repository<TModel> : IRepository<TModel> where TModel : class
{
    public void Add()
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TModel> GetAll()
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TModel> GetByID()
    {
        throw new NotImplementedException();
    }
}
public class HomeController : ApiController
{
    IComponentContext _container;

    public HomeController(IComponentContext container)
    {
        this._container = container;
    }

    public Repository<TModel> Using<TModel>() where TModel :class
    {
        var repository = _container.Resolve(typeof(IRepository<TModel>));
        return repository as Repository<TModel>;
    }

    [HttpGet]
    public IEnumerable<Employee> GetEmployees()
    {
        return Using<Employee>().GetAll();
    }
}
公共类HomeController:ApicController
{
IComponentContext_容器;
公共HomeController(IComponentContext容器)
{
这个._容器=容器;
}
使用()的公共存储库,其中TModel:class
{
var repository=_container.Resolve(typeof(IRepository));
将存储库作为存储库返回;
}
[HttpGet]
公共IEnumerable GetEmployees()
{
使用().GetAll()返回;
}
}
Global.asax

protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);

    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));

    var container = builder.Build(Autofac.Builder.ContainerBuildOptions.None);
    var webApiResolver = new AutofacWebApiDependencyResolver(container);
    GlobalConfiguration.Configuration.DependencyResolver = webApiResolver;
}
受保护的无效应用程序\u Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
var builder=new ContainerBuilder();
RegisterAppController(Assembly.getExecutionGassembly());
builder.RegisterGeneric(typeof(Repository)).As(typeof(IRepository));
var container=builder.Build(Autofac.builder.ContainerBuildOptions.None);
var webApiResolver=新的AutofacWebApiDependencyResolver(容器);
GlobalConfiguration.Configuration.DependencyResolver=webApiResolver;
}

假设我有5个存储库,构造函数注入将解决我提出的请求的所有5个依赖项。我可能不会为每个请求使用5个存储库。因此,我想通过使用()传递类型来动态解析依赖关系,就像我在
中所做的那样。如有任何建议,将不胜感激。。!!谢谢你

不要直接在应用程序组件内部使用容器;这会导致各种各样的问题,比如可维护性和可测试性问题。从应用程序代码中直接解析实例称为服务定位器

作为第一次重构,您可以改为应用该模式。工作单元允许访问底层存储库。例如:

public interface IUnitOfWork
{
    IRepository<TModel> Repository<TModel>();
}

public sealed class HomeController : ApiController
{
    private readonly IUnitOfWork _unitOfWork;

    public HomeController(IUnitOfWork unitOfWork)
    {
        this._unitOfWork = unitOfWork;
    }

    [HttpGet]
    public IEnumerable<Employee> GetEmployees()
    {
        return this._unitOfWork.Repository<Employee>().GetAll();
    }
}
此模式大大简化了应用程序组件,并防止了服务定位器反模式通常导致的缺点

尽管应用工作单元模式可能是朝着正确方向迈出的有用一步,但更好的方法是直接跳过工作单元,直接将所需的存储库注入到应用程序组件中:

public sealed class HomeController : ApiController
{
    private readonly IRepository<Employee> _employeeRepository;

    public HomeController(IRepository<Employee> employeeRepository)
    {
        this._employeeRepository = employeeRepository;
    }

    [HttpGet]
    public IEnumerable<Employee> GetEmployees()
    {
        return this._employeeRepository.GetAll();
    }
}
公共密封类HomeController:ApicController
{
私人只读IRepository\u employeeRepository;
公共家庭管理员(IRepository employeeRepository)
{
这._employeeRepository=employeeRepository;
}
[HttpGet]
公共IEnumerable GetEmployees()
{
返回此项。_employeeRepository.GetAll();
}
}
假设我有5个存储库,构造函数注入将解决我提出的请求的所有5个依赖项。我可能不会为每个请求使用5个存储库

请注意,从性能角度来看,您通常不应该关心是否使用依赖项。在大多数情况下,Autofac的速度足够快,这不太可能在生产系统中造成任何性能问题


然而,从设计的角度来看,如果一个类有许多依赖项,而方法只使用其中的一些依赖项,那么您应该更加担心。这意味着类中的方法几乎没有内聚性。这表明该类应划分为多个较小的类;它基本上是使用直接使用容器来考虑反模式的服务定位器模式。这里有更多信息:我个人会把它分成多个控制器,只注入所需的存储库。@Praveen说,因此,请不要直接使用
容器。在
idependencysolver.GetService
中使用IoC容器解析已注册的类型就足够了。嘿,Steven,你知道这一点吗