我是依赖注入的新手,我决定使用autofac,因为它似乎拥有对MVC5最好的“开箱即用”支持(其他人可能会更好,但我是新手)
我正在创建简单的使用场景,并且在wiki中我在application_start
中的global.asax
中获得了以下代码
protected void Application_Start()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<ArtistController>().InstancePerHttpRequest();
builder.RegisterType<ArtistService>().As<IArtistService>().SingleInstance();
builder.RegisterType<ArtistRepository>().As<IArtistRepository>().SingleInstance();
builder.RegisterType<BandMemberRepository>().As<IBandMemberRepository>).SingleInstance();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
在我的ArtistController
我有这个
私人IArtistService _artistService
;
然后我有一些检索和更新数据的代码,非常简单。这工作正常,我开始了解整个概念。
我的问题是,我是否必须手动注册我使用的所有具体类?我的应用程序最终会成长,我会有很多很多课程,所以这将是一个痛苦的管理。我碰到过这个
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
据我所知,应该为我注册一切,但它没有用。我做错了吗?
autofac网站显示了使用lambdas的示例,因此我将其添加到global.asax
中builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces();
但是没有用,有什么想法吗?
答案 0 :(得分:0)
我通过使用以下属性对其进行大多数(90%以上)注册:
[AttributeUsage(AttributeTargets.Class)]
[JetBrains.Annotations.MeansImplicitUse]
public class AutoRegisterAttribute : Attribute {}
然后我使用这个模块来注册这些类:
public class AutoRegisterModule : Module
{
private readonly Assembly[] _assembliesToScan;
public AutoRegisterModule(params Assembly[] assembliesToScan)
{
_assembliesToScan = assembliesToScan;
}
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(_assembliesToScan)
.Where(t => t.GetCustomAttribute<AutoRegisterAttribute>(false) != null)
.AsSelf()
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
public static AutoRegisterModule ForCallingAssembly()
{
return new AutoRegisterModule(Assembly.GetCallingAssembly());
}
}
因此,当我构建容器时,我通常会这样做:
builder.RegisterModule(AutoRegisterModule.ForCallingAssembly());