C# 实体框架上下文工厂和循环引用

C# 实体框架上下文工厂和循环引用,c#,.net,entity-framework,refactoring,unity-container,C#,.net,Entity Framework,Refactoring,Unity Container,我尝试为实体框架上下文创建一个工厂 1.球门 在assembly DataService中的PersonDataService中,我希望使用以下方法: public void GetPerson(int id) { using(var context = this.contextFactory.Create<IPersonContext>()) { var personRepository = this.repositoryFactory.Creat

我尝试为实体框架上下文创建一个工厂

1.球门 在assembly DataService中的PersonDataService中,我希望使用以下方法:

public void GetPerson(int id)
{
    using(var context = this.contextFactory.Create<IPersonContext>())
    {
         var personRepository = this.repositoryFactory.Create<IPersonRepository>(context);
         return personRepository.Get(id);
    }
}
2.鉴于 在我们的项目中,有一个名为DependencyInjection的程序集,我们在其中设置了所有unity配置,因此该程序集引用了许多项目,包括实体框架所在的程序集DataAccess

ContextFactory应该如下所示:

public class ContextFactory : IContextFactory
{
    public T Create<T>() where T : IDbContext
    {
        return UnityConfig.GetConfiguredContainer().Resolve<T>();
    }
}
assembly DependencyInjection还具有assembly DataService的引用

3.问题
DataService好的,我认为,问题在于决定使用一个程序集来配置容器。我看不出有什么好处

作为解决方案,我建议您使用以下项目结构:

创建具有公共接口的程序集 使用接口的内部实现创建程序集 混淆程序集2中的统一容器 使用UnityContainerExtension类公开Unity容器配置 实例 组合1:

public interface ISecurityService
{
    SignInStatus SignIn(string email, string password, bool isPersistent);
    void SignOut();
}
大会2:

internal sealed class SecurityService : ISecurityService
{
    private readonly SignInManager<User, long> _signInManager;
    public SecurityService(SignInManager<User, long> signInManager)
    {
        _signInManager = signInManager;
        _signInManager.UserManager.UserValidator = new UserValidator<User, long>(_signInManager.UserManager)
        {
            AllowOnlyAlphanumericUserNames = false
        };
    }

    public SignInStatus SignIn(string email, string password, bool isPersistent)
    {
        var status = _signInManager.PasswordSignIn(email, password, isPersistent, shouldLockout: false);
        return status;
    }

    public void SignOut()
    {
        _signInManager.AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie,
            DefaultAuthenticationTypes.TwoFactorCookie);
    }
}

public sealed class ApplicationExtension : UnityContainerExtension
{
    protected override void Initialize()
    {
        Container.RegisterType<IAuthenticationManager>(new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
        Container.RegisterType<IPrincipal>(new InjectionFactory(c => HttpContext.Current.User));
        Container.RegisterType<ISecurityService, SecurityService>(new PerRequestLifetimeManager());
    }
}
优点:

您的接口是公共的,并且与实现分离 实现是内部的,只能通过接口使用 从程序集公开配置的容器
public class UnityConfig
{
    public static void RegisterTypes(IUnityContainer container)
    {
        var container = new UnityContainer();
        container.AddExtension(new ApplicationExtension());
        //use container
    }
}