更新09.08.2018
Unity正在开发中,但我还没有时间测试它如何与ASP.NET Core框架配合使用.
更新15.03.2018
此解决方案适用于在使用.NET Framework 4.5.2而不是 .NET Core Framework 时使用ASP.NET Core v1和Unity的特定问题.我不得不使用这个设置,因为我需要一些.Net 4.5.2 DLL,但对于任何重新开始的人我都不会推荐这种方法.此外,Unity还没有进一步开发(据我所知)所以我建议将Autofac框架用于新项目.有关如何执行此操作的详细信息,请参阅此帖子.
简介
我正在使用ASP.NET和MVC构建Web应用程序.此应用程序依赖于某些服务(WCF服务,数据存储区服务等).现在为了保持良好和解耦,我想使用DI(Dependecy Injection)框架,特别是Unity.
初步研究
我发现这篇博文,但遗憾的是它不起作用.这个想法虽然很好.
它基本上表示您不应将ServiceCollection中注册的所有服务注册到您自己的容器中,而应引用默认的ServiceProvider.
所以.如果需要解决某些问题,则调用默认的ServiceProvider,如果没有解析,则使用自定义UnityContainer解析类型.
问题
MVC总是尝试使用默认的ServiceProvider解析Controller.
此外,我注意到即使控制器得到正确解析,我也永远不会"混合"依赖关系.现在,如果我想使用我的一个服务而且还要使用ASP的IOptions接口,则该类永远无法解析,因为这两个容器中没有一个具有两种类型的解析.
我需要什么
所以回顾一下我需要以下几点:
编辑:
所以问题是如何实现这些要点?
有没有办法让统一容器将自己传递给对象?
即:
public class Something {
public Something(IUnityContainer container) {
...
}
}
Run Code Online (Sandbox Code Playgroud) 当我使用Unity IOC时,我想知道何时使用builddup以及何时使用resolve.
我什么时候打电话拆机?
谢谢
我有这门课:
public class Repo
{
public Repo() : this(ConfigurationManager.AppSettings["identity"], ConfigurationManager.AppSettings["password"])
{
}
public Repo(string identity,string password)
{
//Initialize properties.
}
}
Run Code Online (Sandbox Code Playgroud)
我在web.config中添加了一行,以便Unity容器自动构建此类型.
但在执行我的应用程序期间,我收到此错误消息:
"System.InvalidOperationException : the parameter identity could not be resolved when attempting to call constructor Repo(String identity, String password) -->Microsoft.Practices.ObjectBuilder2.BuildFailedException : The current Build operation ...."
Run Code Online (Sandbox Code Playgroud)
1)为什么Unity不使用默认构造函数?
2)假设我希望Unity使用第二个构造函数(参数构造函数),如何通过配置文件将该信息传递给Unity?
我想使用unity创建一个类的实例,其中类有两个具有相同参数数量的构造函数.
这是实例化:
_unityContainer.Resolve<IGradeType>(new ParameterOverride("gradeTypeStringFromXmlFile", gradeTypeStringFromXmlFile));
Run Code Online (Sandbox Code Playgroud)
以下是构造函数:
public GradeType(string gradeTypeStringFromXmlFile)
{
_gradeTypeStringFromXmlFile = gradeTypeStringFromXmlFile;
}
public GradeType(Enum.GradeType gradeType)
{
_gradeType = gradeType;
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试这样做,我得到一个例外,说明 类型GradeType有多个长度为1的构造函数.无法消除歧义.
我可以在一个构造函数上设置属性[InjectionConstructor]以使其与一个一起工作,但是我不能使用另一个构造函数创建一个具有单元的实例.
是否有一些方法让多个构造函数具有相同数量的参数并仍然使用unity来创建实例?
我有一个MVC WebApi owin(软托管)项目,它使用Unity来解析控制器依赖项
看起来像这样
public class PacientaiController : ODataController
{
private readonly IEntityRepo<Ent.Pacientas> repo;
public PacientaiController(IEntityRepo<Ent.Pacientas> repo)
{
this.repo = repo;
}
Run Code Online (Sandbox Code Playgroud)
我试图解决的问题是 - 如何将'OwinContex'传递给回购.
public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
{
public PacientasEntityRepo(IOwinContext ctx)
{
.........
Run Code Online (Sandbox Code Playgroud)
如果我尝试在这里注册它 Startup.cs
Container.RegisterType<IOwinContext>(new InjectionFactory(o => HttpContext.Current.GetOwinContext()));
Run Code Online (Sandbox Code Playgroud)
我得到一个空引用,说这HttpContext.Current是NULL
这里的主要思想是将当前经过身份验证的用户传递给repo,因为Repo托管逻辑以查询数据库,具体取决于用户.(如果用户是Admin,则返回此数据,如果用户是guest - 返回此数据)
关键是 - 这是一个自我主持人!
我试图将依赖注入到自定义中AuthorizeAttribute,如下所示:
public class UserCanAccessArea : AuthorizeAttribute
{
readonly IPermissionService permissionService;
public UserCanAccessArea() :
this(DependencyResolver.Current.GetService<IPermissionService>()) { }
public UserCanAccessArea(IPermissionService permissionService)
{
this.permissionService = permissionService;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
string AreaID =
httpContext.Request.RequestContext.RouteData.Values["AreaID"] as string;
bool isAuthorized = false;
if (base.AuthorizeCore(httpContext))
isAuthorized = permissionService.UserCanAccessArea(AreaID, httpContext.User);
return isAuthorized;
}
}
Run Code Online (Sandbox Code Playgroud)
这有效,但似乎是作为一个单身人士解决,这意味着我得到了我以前的问题中描述的问题
我想要做的是使用属性注入但由于我的属性本身没有被Unity解决,我无法找到一种方法来配置容器来拦截和解析属性.我尝试过以下方法:
public class UserCanAccessArea : AuthorizeAttribute
{
public IPermissionService permissionService { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
string AreaID =
httpContext.Request.RequestContext.RouteData.Values["AreaID"] …Run Code Online (Sandbox Code Playgroud) c# authentication asp.net-mvc dependency-injection unity-container
我刚刚开始使用微软的Unity应用程序块依赖注入库,而且我已经失败了.
这是我的IoC类,它将处理我的具体类到它们的接口类型的实例化(所以每次我在控制器中需要一个存储库时,我不必在IoC容器上保持名为Resolve):
public class IoC
{
public static void Intialise(UnityConfigurationSection section, string connectionString)
{
_connectionString = connectionString;
_container = new UnityContainer();
section.Configure(_container);
}
private static IUnityContainer _container;
private static string _connectionString;
public static IMovementRepository MovementRepository
{
get { return _container.Resolve<IMovementRepository>(); }
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我的想法是,从我的控制器,我可以做到以下几点:
_repository = IoC.MovementRepository;
Run Code Online (Sandbox Code Playgroud)
我目前收到错误:
异常是:InvalidOperationException - 无法构造String类型.您必须配置容器以提供此值.
现在,我假设这是因为我的映射具体实现需要为其构造函数提供单个字符串参数.具体课程如下:
public sealed class MovementRepository : Repository, IMovementRepository
{
public MovementRepository(string connectionString) : base(connectionString) { }
}
Run Code Online (Sandbox Code Playgroud)
其中继承自:
public abstract class Repository
{
public Repository(string connectionString)
{
_connectionString = …Run Code Online (Sandbox Code Playgroud) c# dependency-injection inversion-of-control unity-container repository-pattern
我正在使用Entity Framework 5和Code First Migrations.我有一个DataStore类派生自DbContext:
public class DataStore : DbContext, IDataStore
{
public int UserID { get; private set; }
public DataStore(int userId, string connectionString) : base(connectionString)
{
UserID = userId;
}
public virtual IDbSet<User> Users { get; set; }
// Rest of code here
}
Run Code Online (Sandbox Code Playgroud)
还有一个创建类实例的工厂DataStore类:
public class DataStoreFactory : Disposable, IDataStoreFactory
{
private DataStore _database;
private int _userId;
private string _connectionString;
public DataStoreFactory(int userId, string connectionString)
{
_userId = userId;
_connectionString = …Run Code Online (Sandbox Code Playgroud) c# entity-framework dependency-injection unity-container asp.net-mvc-4
我使用Unity成功为所有常规构造注射,如仓库等,但我不能让它与ASP.NET身份类的工作.设置是这样的:
public class AccountController : ApiController
{
private UserManager<ApplicationUser> _userManager { get; set; }
public AccountController(UserManager<ApplicationUser> userManager)
{
if (userManager == null) { throw new ArgumentNullException("userManager"); }
_userManager = userManager;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
使用Unity的这些配置:
unity.RegisterType<AccountController>();
unity.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
unity.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager());
Run Code Online (Sandbox Code Playgroud)
这与Autofac,Ninject的其他帖子相同,例如,但在我的情况下它不起作用.错误消息是:
尝试创建"AccountController"类型的控制器时发生错误.确保控制器具有无参数的公共构造函数.手动创作当然是:
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>("Mongo")))
{
}
Run Code Online (Sandbox Code Playgroud)
怎么了?
UPDATE
正如@emodendroket所建议的,缩短代码就可以了.不需要Unity.Mvc包.
unity.RegisterType<IUserStore<IdentityUser>,
MyCustomUserStore>(new HierarchicalLifetimeManager());
Run Code Online (Sandbox Code Playgroud)
和
public AccountController(UserManager<IdentityUser> _userManager,
IAccountRepository _account)
{
// ...
Run Code Online (Sandbox Code Playgroud) c# asp.net dependency-injection unity-container asp.net-identity