3

私はタマネギアーキテクチャのこの実装に基づくアーキテクチャを使用しています。NHibernatesのデフォルトのロガー(log4net)をNLogに変更することに挑戦することにしました。NLogの構成方法は理解していますが、LogerFactoryクラスのロガーの依存関係を解決するのに問題があります。現在、私のNHibernateプロジェクトは私のロギングインターフェイスしか知りません。NHibernateプロジェクトで依存関係を解決するにはどうすればよいですか?

これが現在の私のプログラム構造です。コンソールアプリはninjectを初期化し、LoggingModuleやRepositoryModuleを含むモジュールをセットアップします。リポジトリから何かが初めて必要になると、SessionHelperクラスがセッションを構築し、NHibernateを構成します。これは、NHibernateが私のLoggerFactoryを呼び出す場所です(LoggerFactoryはNHibernates ILoggerFactoryを実装します)。NHibernateはLoggerFor(Type type);を呼び出します。タイプはNHibernate.Cfg.Configurationとして渡されます。ここから、ILoggingServiceを介してNLogのインスタンスを取得する必要があります。これは、混乱しているところです。ここでこの依存関係を解決するにはどうすればよいですか?私のコンソールアプリは、カーネルを構築してモジュールをロードした場所であるため、解像度を認識しています。ここに別のカーネルを設定するだけですか?これを解決するための最良の方法は何ですか?

編集:これが私の現在のコードです:

Program.cs

namespace ZeroBase.ManualConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            IKernel kernel = CreateKernel();

            CoreService service = new CoreService(
                kernel.Get<ZeroBase.Domain.Interfaces.IUserRepository>(), 
                kernel.Get<ZeroBase.Domain.Interfaces.ICommentRepository>());

            //.........

        }

        static IKernel CreateKernel()
        {
            IKernel kernel = new StandardKernel();
            RegisterServices(kernel);
            return kernel;
        }

        static void RegisterServices(IKernel kernel)
        {
            // Bind Core Service
            kernel.Bind<ICoreService>().To<CoreService>();

            // Add data and infrastructure modules
            var modules = new List<INinjectModule>
            {
                new ConfigModule(),
                new LoggingModule(),
                new RepositoryModule()
            };

            kernel.Load(modules);
        }

    }
}

LoggingModule.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject.Modules;
using ZeroBase.Infrastructure.Interfaces;
using NLog.Config;
using NLog;
using ZeroBase.Infrastructure.Logging;

namespace ZeroBase.Infrastructure.DependencyResolution
{
    public class LoggingModule : NinjectModule
    {
        public override void Load()
        {
            ILoggingService logger = GetLoggingService();
            Bind<ILoggingService>().ToConstant(logger);
        }

        private ILoggingService GetLoggingService()
        {
            ConfigurationItemFactory.Default.LayoutRenderers
                .RegisterDefinition("utc_date", typeof(UtcDateRenderer));
            ConfigurationItemFactory.Default.LayoutRenderers
                .RegisterDefinition("web_variables", typeof(WebVariablesRenderer));
            ILoggingService logger = (ILoggingService)LogManager.GetLogger("NLogLogger", typeof(LoggingService));
            return logger;
        }
    }
}

RepositoryModule.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Ninject;
using Ninject.Modules;

using ZeroBase.Infrastructure.Interfaces;
using ZeroBase.Domain.Interfaces;
using ZeroBase.Infrastructure.Data;

namespace ZeroBase.Infrastructure.DependencyResolution
{
    public class RepositoryModule : NinjectModule
    {
        public override void Load()
        {
            SetupLogging();
            BindRepositories();
        }

        private void SetupLogging()
        {
            // Get logging service
            var loggingService = Kernel.Get<ILoggingService>();

        }

        private void BindRepositories()
        {
            // Get config service
            var configService = Kernel.Get<IConfigService>();

            // Bind repositories
            Bind<IUserRepository>().To<UserRepository>()
                .WithConstructorArgument("connectionString",    configService.ZeroBaseConnection);
            Bind<ICommentRepository>().To<CommentRepository>()
                .WithConstructorArgument("connectionString",    configService.ZeroBaseConnection);
        }
    }
}

RepositoryBase.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZeroBase.Domain.Interfaces;

namespace ZeroBase.Infrastructure.Data
{
    public class RepositoryBase<T> : IRepositoryBase<T>
    {
        protected SessionHelper _nhibernate;
        protected string _connectionString;

        public RepositoryBase(string connectionString)
        {
            _connectionString = connectionString;
            _nhibernate = new SessionHelper(_connectionString);
        }

        //....
    }
}

SessionHelper.cs NHibernateセッションを構築し、構成します。connectionStringが挿入されていることに注意してください。ここにロギングサービスを簡単に挿入できます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using ZeroBase.Infrastructure.Data;
using FluentNHibernate.Automapping;
using ZeroBase.Domain.Entities;
using ZeroBase.Infrastructure.Interfaces;

namespace ZeroBase.Infrastructure.Data
{
    public class SessionHelper
    {
        private ISessionFactory _sessionFactory;
        private string _connectionString;

        public SessionHelper(string connectionString)
        {
            _connectionString = connectionString;
        }

        private ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                    InitializeSessionFactory();

                return _sessionFactory;
            }
        }

        private void InitializeSessionFactory()
        {
            _sessionFactory = Fluently.Configure()

                // Set up database connection
                .Database(MsSqlConfiguration.MsSql2005
                    .ConnectionString(x => x.Is(_connectionString))
                    //.ShowSql()
                )

                // Use class mappings
                .Mappings(m => m.FluentMappings
                    .AddFromAssemblyOf<UserMap>()
                    .AddFromAssemblyOf<ZeroBase.Infrastructure.Data.RACS3.UserMap>())

                .ExposeConfiguration(c => {
                        c.SetInterceptor(new AuditInterceptor());
                    }
                )

                .BuildSessionFactory();
        }

        public ISession OpenSession()
        {
            return SessionFactory.OpenSession();
        }
    }
}

LoggerFactory.csNHibernateがロギングに使用するようにapp.configを介して構成されます。これは、依存関係の問題が発生している場所です。これはNHibernateと一緒に住んでいます。ここでNLogを簡単に参照して、NHibernateに接続できますが、NHibernateが使用しているロギングフレームワークを気にしないようにします。これが、自分のインターフェースのみを扱い、Ninjectに具体的な実装を注入させたい理由です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using ZeroBase.Infrastructure.Interfaces;

namespace ZeroBase.Infrastructure.Data
{
    public class LoggerFactory : ILoggerFactory
    {
        public IInternalLogger LoggerFor(Type type)
        {
            //ILoggingService logService;

            // Get resolved LoggingService

            //return new NLogLogger(LogManager.GetLogger(type.FullName));
            //return new Logger(logService.GetLogger(type.FullName));
            return null;
        }

        public IInternalLogger LoggerFor(string keyName)
        {
            //ILoggingService logService;

            // Get resolved LoggingService

            //return new NLogLogger(LogManager.GetLogger(keyName));
            //return new Logger(logService.GetLogger(keyName));
            return null;
        }
    }

    public class Logger : IInternalLogger
    {
        private readonly ILoggingService logger;

        public Logger(ILoggingService _logger)
        {
            logger = _logger;
        }

        //....
    }
}
4

2 に答える 2

1

Common.Loggingを介したNHibernateでのNLogの使用:

http://nhibernate.info/doc/howto/various/using-nlog-via-common-logging-with-nhibernate.html

于 2012-06-19T12:00:43.337 に答える
1

Kernalを初期化した直後に、静的KernalプロパティをLoggerFactoryクラスに追加し、それをProgram.Mainに設定できないのはなぜですか?

次に、LoggerFor実装で、静的カーネルプロパティを参照するだけで、正しくバインドされた実装を取得できます。

于 2012-06-20T19:01:19.147 に答える