将 Castle.Windsor 与 SSW Data Onion 一起用于 Entity Framework 6

Use Castle.Windsor with SSW Data Onion for Entity Framework 6

我正在努力将遗留数据库与 Asp.Net Zero. I created the model classes using EntityFramework Reverse POCO Generator in a separate Models class library project. I also reversed engineered the DbContext into a separate Data class library project. I would like to use the Data Onion framework for my repositories and unit of work. When I use the recommended IOC container Autofaq 集成,我的测试 Winform 应用程序工作正常。

但是,Web 项目利用了 Castle.Windsor我不确定如何进行接线。

我正在创建一个名为 ClientDesktopContainer:

的新容器
internal class ClientDesktopContainer : WindsorContainer
{
    public ClientDesktopContainer()
    {
        RegisterComponents();
    }

    private void RegisterComponents()
    {
        var connectionstring = ConfigurationManager.ConnectionStrings["MyDbContext"].ConnectionString;

        // Data Onion
        Component.For<IDbContextFactory>().ImplementedBy<DbContextFactory>()
            .DependsOn(new DbContextConfig(connectionstring, typeof(MyDbContext), new MigrateToLatestVersion(new Seeder())));
        Component.For<IDbContextScope>().ImplementedBy<DbContextScope>();
        Component.For<IDbContextScopeFactory>().ImplementedBy<DbContextScopeFactory>();
        Component.For<IAmbientDbContextLocator>().ImplementedBy<AmbientDbContextLocator>();
        Component.For<IDbContextReadOnlyScope>().ImplementedBy<DbContextReadOnlyScope>();

        // Data Onion Unit of Work
        Component.For<IRepositoryLocator>().ImplementedBy<RepositoryLocator>();
        // Component.For<IRepositoryResolver>().ImplementedBy<CastleWindsorRepositoryResolver>();
        Component.For<IUnitOfWorkFactory>().ImplementedBy<UnitOfWorkFactory>();
        Component.For<IUnitOfWork>().ImplementedBy<UnitOfWork>();
        Component.For<IReadOnlyUnitOfWork>().ImplementedBy<IReadOnlyUnitOfWork>();

        // Custom
        Component.For<IRepository<Enrollment>>()
                 .ImplementedBy<BaseRepository<Enrollment, MyDbContext>>();
}

我的应用程序调用代码是Program:

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        IoC.Initialize(new ClientDesktopContainer());

        var dbContextScopeFactor = IoC.Resolve<IDbContextScopeFactory>();
        using (var dbReadOnly = dbContextScopeFactor.CreateReadOnly())
        {
            var context = dbReadOnly.DbContexts.Get<MyDbContext>();

            var individuals = context.Enrollments.ToList();
            foreach (var individual in individuals)
            {
                // do stuff
            }
        }

        Application.Run(new ViewMain());
    }
}

我创建了一个静态 IOC:

public static class IoC
{
    private static IWindsorContainer _container;

    public static void Initialize(IWindsorContainer container)
    {
        _container = container;
    }

    public static T Resolve<T>()
    {
        try
        {
            return _container.Resolve<T>();
        }
        catch
        {
            throw;
        }
    }
}

Data Onion 文档提到为 IRepositoryResolver 注册自定义解析器。

我创建了一个 CastleWindsorRepositoryResolver:

public class CastleWindsorRepositoryResolver : IRepositoryResolver
{
    public IRepository<TEntity> Resolve<TEntity>() where TEntity : class
    {
        // TODO: Resolve wire-up goes here
        throw new System.NotImplementedException();
    }
}

我收到 ComponentNotFoundExpection

已更新以修复 DbContextFactory 的构造函数参数(到 RegisterComponents 方法):

   var dbContextConfig = new DbContextConfig[]
        {
            new DbContextConfig(
                connectionString,
            typeof(MyDbContext),
            new MigrateToLatestVersion(new Seeder())
            ) 
        };

        // Data Onion
        Register(Component.For<IDbContextFactory>().ImplementedBy<DbContextFactory>()
            .DependsOn(Dependency.OnValue<DbContextConfig[]>(dbContextConfig)));

在以下位置添加对 Register 的调用:

internal class ClientDesktopContainer : WindsorContainer
{
    public ClientDesktopContainer()
    {
        RegisterComponents();
    }

    private void RegisterComponents()
    {
        var connectionstring = ConfigurationManager.ConnectionStrings["MyDbContext"].ConnectionString;

         /* HERE CALL TO REGISTER: */
         this.Register(

        // Data Onion
        Component.For<IDbContextFactory>().ImplementedBy<DbContextFactory>()
            .DependsOn(new DbContextConfig(connectionstring, typeof(MyDbContext), new MigrateToLatestVersion(new Seeder()))),
        Component.For<IDbContextScope>().ImplementedBy<DbContextScope>(),
        Component.For<IDbContextScopeFactory>().ImplementedBy<DbContextScopeFactory>(),
        Component.For<IAmbientDbContextLocator>().ImplementedBy<AmbientDbContextLocator>(),
        Component.For<IDbContextReadOnlyScope>().ImplementedBy<DbContextReadOnlyScope>(),

        // Data Onion Unit of Work
        Component.For<IRepositoryLocator>().ImplementedBy<RepositoryLocator>(),
        // Component.For<IRepositoryResolver>().ImplementedBy<CastleWindsorRepositoryResolver>(),
        Component.For<IUnitOfWorkFactory>().ImplementedBy<UnitOfWorkFactory>(),
        Component.For<IUnitOfWork>().ImplementedBy<UnitOfWork>(),
        Component.For<IReadOnlyUnitOfWork>().ImplementedBy<IReadOnlyUnitOfWork>(),

        // Custom
        Component.For<IRepository<Enrollment>>()
                 .ImplementedBy<BaseRepository<Enrollment, MyDbContext>>() );
}

没有 Register 你只是在创建注册对象 而没有 实际上将类型放入容器中。另一件可能有帮助的事情是,默认情况下,Castle 会将组件注册为 singletons,将 LifestyleTranscientPerWebRequest 添加到您的 UnitOfWork 注册中。