使用Castle.Windsor和SSW Data Onion for Entity Framework 6

时间:2016-05-26 13:36:23

标签: c# castle-windsor

我正在努力将遗留数据库与Asp.Net Zero集成。我在一个单独的Models类库项目中使用EntityFramework Reverse POCO Generator创建了模型类。我还将DbContext设计为一个单独的Data类库项目。我想将Data Onion框架用于我的存储库和工作单元。当我使用推荐的IOC容器Autofaq时,我的Test 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 Exception

更新以修复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)));

1 个答案:

答案 0 :(得分:0)

在以下位置添加对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会将组件注册为单例添加LifestyleTranscientPerWebRequest到您的UnitOfWork注册。