我正在使用MVC项目autofac。 我有另一个核心业务项目(dll库)。 在这个核心中,我想使用autofac来检索一些接口。
现在,如果我在MVC应用程序中,我可以使用
DependencyResolver.Current.GetService<IMyService>();
用于检索服务。 但是在库中如何在不将其作为属性传递给某些类声明的情况下检索服务?
DependencyResolver仅在MVC项目中定义。
这是最佳做法吗?
答案 0 :(得分:2)
我发现您的方法存在以下问题:
DepdencyResolver
在System.Web.Mvc中定义,您的BL项目不应该引用该程序集。避免BL项目中的System.Web.Mvc依赖
我发现一个特定的Locator<T>
是一种切实可行的方法,它绕过服务定位器模式的“open to everything” - 和 static -issue:
public interface ILocator<T> // defined in some *CORE* project
{
T Locate();
}
public class AutofacLocator<T> : ILocator<T> // defined and injected in your *FRONTEND* project
{
public AutofacLocator(ILifetimeScope lifetimeScope)
{
this.LifetimeScope = lifetimeScope;
}
public virtual T Locate()
{
var service = this.LifetimeScope.Resolve<T>();
return service;
}
}
这可以简单地注册为open generic:
builder.RegisterGeneric(typeof(AutofacLocator<>))
.As(typeof(ILocator<>))
.InstancePerDependency();
因此,您不必依赖静态DependencyResolver.Current
,而是创建自己的解析器,并将其注入BL-class'ctor:
public class SomeBusinessLogic
{
public SomeBusinessLogic(ILocator<SomeDependency> someDependencyLocator)
{
}
}
使用Ctor-Injection代替服务定位器模式
另一种方法是简单地将T
- 实例的依赖关系定义为ctor-parameter,并让Autofac构建BL-class的实例:
public class SomeBusinessLogic // defined in your *BL* project
{
public SomeBusinessLogic(SomeDependency someDependency)
{
}
}
var someBusinessLogic = DependencyResolver.Current.GetService<SomeBusinessLogic>(); // in your *FRONTEND* project