Commit 04e69807 authored by 阿星Plus's avatar 阿星Plus

ComponentRegistration

parent 066fa075
namespace Plus.Configuration.Startup
{
internal class EventBusConfiguration : IEventBusConfiguration
{
public bool UseDefaultEventBus { get; set; }
public EventBusConfiguration()
{
UseDefaultEventBus = true;
}
}
}
\ No newline at end of file
using Plus.Collections;
using Plus.Runtime.Validation.Interception;
using System;
using System.Collections.Generic;
namespace Plus.Configuration.Startup
{
public class ValidationConfiguration : IValidationConfiguration
{
public List<Type> IgnoredTypes
{
get;
}
public ITypeList<IMethodParameterValidator> Validators
{
get;
}
public ValidationConfiguration()
{
IgnoredTypes = new List<Type>();
Validators = new TypeList<IMethodParameterValidator>();
}
}
}
\ No newline at end of file
using Castle.MicroKernel.Registration; using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration; using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor; using Castle.Windsor;
using Plus.Configuration.Startup;
using Plus.Domain.Uow;
using Plus.Modules;
using Plus.Reflection;
using Plus.Runtime.Caching.Configuration;
namespace Plus.Dependency.Installers namespace Plus.Dependency.Installers
{ {
...@@ -9,7 +14,14 @@ namespace Plus.Dependency.Installers ...@@ -9,7 +14,14 @@ namespace Plus.Dependency.Installers
public void Install(IWindsorContainer container, IConfigurationStore store) public void Install(IWindsorContainer container, IConfigurationStore store)
{ {
container.Register( container.Register(
// TODO... Component.For<IUnitOfWorkDefaultOptions, UnitOfWorkDefaultOptions>().ImplementedBy<UnitOfWorkDefaultOptions>().LifestyleSingleton(),
Component.For<IPlusStartupConfiguration, PlusStartupConfiguration>().ImplementedBy<PlusStartupConfiguration>().LifestyleSingleton(),
Component.For<IPlusModuleManager, PlusModuleManager>().ImplementedBy<PlusModuleManager>().LifestyleSingleton(),
Component.For<IAssemblyFinder, AssemblyFinder>().ImplementedBy<AssemblyFinder>().LifestyleSingleton(),
Component.For<ITypeFinder, TypeFinder>().ImplementedBy<TypeFinder>().LifestyleSingleton(),
Component.For<ICachingConfiguration, CachingConfiguration>().ImplementedBy<CachingConfiguration>().LifestyleSingleton(),
Component.For<IValidationConfiguration, ValidationConfiguration>().ImplementedBy<ValidationConfiguration>().LifestyleSingleton(),
Component.For<IEventBusConfiguration, EventBusConfiguration>().ImplementedBy<EventBusConfiguration>().LifestyleSingleton()
); );
} }
} }
......
using Plus.Dependency;
namespace Plus.Domain.Repositories
{
public interface IRepository : ITransientDependency
{
}
}
\ No newline at end of file
using Plus.Domain.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
namespace Plus.Domain.Uow
{
internal class UnitOfWorkDefaultOptions : IUnitOfWorkDefaultOptions
{
public TransactionScopeOption Scope { get; set; }
public bool IsTransactional { get; set; }
public TimeSpan? Timeout { get; set; }
public bool IsTransactionScopeAvailable { get; set; }
public IsolationLevel? IsolationLevel { get; set; }
public IReadOnlyList<DataFilterConfiguration> Filters => _filters;
private readonly List<DataFilterConfiguration> _filters;
public List<Func<Type, bool>> ConventionalUowSelectors { get; }
public UnitOfWorkDefaultOptions()
{
_filters = new List<DataFilterConfiguration>();
IsTransactional = true;
Scope = TransactionScopeOption.Required;
IsTransactionScopeAvailable = true;
ConventionalUowSelectors = new List<Func<Type, bool>>
{
type => typeof(IRepository).IsAssignableFrom(type)
};
}
public void RegisterFilter(string filterName, bool isEnabledByDefault)
{
if (_filters.Any(f => f.FilterName == filterName))
{
throw new PlusException("There is already a filter with name: " + filterName);
}
_filters.Add(new DataFilterConfiguration(filterName, isEnabledByDefault));
}
public void OverrideFilter(string filterName, bool isEnabledByDefault)
{
_filters.RemoveAll(f => f.FilterName == filterName);
_filters.Add(new DataFilterConfiguration(filterName, isEnabledByDefault));
}
}
}
\ No newline at end of file
using Plus.Modules;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Plus.Reflection
{
public class AssemblyFinder : IAssemblyFinder
{
private readonly IPlusModuleManager _moduleManager;
public AssemblyFinder(IPlusModuleManager moduleManager)
{
_moduleManager = moduleManager;
}
public List<Assembly> GetAllAssemblies()
{
var assemblies = new List<Assembly>();
foreach (var module in _moduleManager.Modules)
{
assemblies.Add(module.Assembly);
assemblies.AddRange(module.Instance.GetAdditionalAssemblies());
}
return assemblies.Distinct().ToList();
}
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.Reflection;
namespace Plus.Reflection
{
/// <summary>
/// 获取程序集接口
/// </summary>
public interface IAssemblyFinder
{
/// <summary>
/// 获取程序集列表
/// </summary>
/// <returns></returns>
List<Assembly> GetAllAssemblies();
}
}
\ No newline at end of file
using System;
namespace Plus.Reflection
{
public interface ITypeFinder
{
Type[] Find(Func<Type, bool> predicate);
Type[] FindAll();
}
}
\ No newline at end of file
using Castle.Core.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Plus.Reflection
{
public class TypeFinder : ITypeFinder
{
public ILogger Logger { get; set; }
private readonly IAssemblyFinder _assemblyFinder;
private readonly object _syncObj = new object();
private Type[] _types;
public TypeFinder(IAssemblyFinder assemblyFinder)
{
_assemblyFinder = assemblyFinder;
Logger = NullLogger.Instance;
}
public Type[] Find(Func<Type, bool> predicate)
{
return GetAllTypes().Where(predicate).ToArray();
}
public Type[] FindAll()
{
return GetAllTypes().ToArray();
}
private Type[] GetAllTypes()
{
if (_types == null)
{
lock (_syncObj)
{
if (_types == null)
{
_types = CreateTypeList().ToArray();
}
}
}
return _types;
}
private List<Type> CreateTypeList()
{
var allTypes = new List<Type>();
var assemblies = _assemblyFinder.GetAllAssemblies().Distinct();
foreach (var assembly in assemblies)
{
try
{
Type[] typesInThisAssembly;
try
{
typesInThisAssembly = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
typesInThisAssembly = ex.Types;
}
if (typesInThisAssembly.IsNullOrEmpty())
{
continue;
}
allTypes.AddRange(typesInThisAssembly.Where(type => type != null));
}
catch (Exception ex)
{
Logger.Warn(ex.ToString(), ex);
}
}
return allTypes;
}
}
}
\ No newline at end of file
using System;
namespace Plus.Runtime.Caching.Configuration
{
internal class CacheConfigurator : ICacheConfigurator
{
public string CacheName { get; private set; }
public Action<ICache> InitAction { get; private set; }
public CacheConfigurator(Action<ICache> initAction)
{
InitAction = initAction;
}
public CacheConfigurator(string cacheName, Action<ICache> initAction)
{
CacheName = cacheName;
InitAction = initAction;
}
}
}
\ No newline at end of file
using Plus.Configuration.Startup;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
namespace Plus.Runtime.Caching.Configuration
{
internal class CachingConfiguration : ICachingConfiguration
{
public IPlusStartupConfiguration PlusConfiguration { get; private set; }
public IReadOnlyList<ICacheConfigurator> Configurators
{
get { return _configurators.ToImmutableList(); }
}
private readonly List<ICacheConfigurator> _configurators;
public CachingConfiguration(IPlusStartupConfiguration plusConfiguration)
{
PlusConfiguration = plusConfiguration;
_configurators = new List<ICacheConfigurator>();
}
public void ConfigureAll(Action<ICache> initAction)
{
_configurators.Add(new CacheConfigurator(initAction));
}
public void Configure(string cacheName, Action<ICache> initAction)
{
_configurators.Add(new CacheConfigurator(cacheName, initAction));
}
}
}
\ No newline at end of file
using System;
namespace Plus.Runtime.Caching.Configuration
{
/// <summary>
/// 已注册的缓存配置
/// </summary>
public interface ICacheConfigurator
{
/// <summary>
/// 缓存的名称
/// </summary>
string CacheName { get; }
/// <summary>
/// 配置操作,在创建缓存之后调用
/// </summary>
Action<ICache> InitAction { get; }
}
}
\ No newline at end of file
using Plus.Configuration.Startup;
using System;
using System.Collections.Generic;
namespace Plus.Runtime.Caching.Configuration
{
/// <summary>
/// 缓存配置接口
/// </summary>
public interface ICachingConfiguration
{
/// <summary>
/// 获取 Plus 配置对象。
/// </summary>
IPlusStartupConfiguration PlusConfiguration { get; }
IReadOnlyList<ICacheConfigurator> Configurators { get; }
void ConfigureAll(Action<ICache> initAction);
void Configure(string cacheName, Action<ICache> initAction);
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Plus.Runtime.Caching
{
/// <summary>
/// Defines a cache that can be store and get items by keys.
/// </summary>
public interface ICache : IDisposable
{
/// <summary>
/// Unique name of the cache.
/// </summary>
string Name { get; }
/// <summary>
/// Default sliding expire time of cache items.
/// Default value: 60 minutes (1 hour).
/// Can be changed by configuration.
/// </summary>
TimeSpan DefaultSlidingExpireTime { get; set; }
/// <summary>
/// Default absolute expire time of cache items.
/// Default value: null (not used).
/// </summary>
TimeSpan? DefaultAbsoluteExpireTime { get; set; }
/// <summary>
/// Gets an item from the cache.
/// This method hides cache provider failures (and logs them),
/// uses the factory method to get the object if cache provider fails.
/// </summary>
/// <param name="key">Key</param>
/// <param name="factory">Factory method to create cache item if not exists</param>
/// <returns>Cached item</returns>
object Get(string key, Func<string, object> factory);
/// <summary>
/// Gets items from the cache.
/// This method hides cache provider failures (and logs them),
/// uses the factory method to get the object if cache provider fails.
/// </summary>
/// <param name="keys">Keys</param>
/// <param name="factory">Factory method to create cache item if not exists</param>
/// <returns>Cached item</returns>
object[] Get(string[] keys, Func<string, object> factory);
/// <summary>
/// Gets an item from the cache.
/// This method hides cache provider failures (and logs them),
/// uses the factory method to get the object if cache provider fails.
/// </summary>
/// <param name="key">Key</param>
/// <param name="factory">Factory method to create cache item if not exists</param>
/// <returns>Cached item</returns>
Task<object> GetAsync(string key, Func<string, Task<object>> factory);
/// <summary>
/// Gets items from the cache.
/// This method hides cache provider failures (and logs them),
/// uses the factory method to get the object if cache provider fails.
/// </summary>
/// <param name="keys">Keys</param>
/// <param name="factory">Factory method to create cache item if not exists</param>
/// <returns>Cached items</returns>
Task<object[]> GetAsync(string[] keys, Func<string, Task<object>> factory);
/// <summary>
/// Gets an item from the cache or null if not found.
/// </summary>
/// <param name="key">Key</param>
/// <returns>Cached item or null if not found</returns>
object GetOrDefault(string key);
/// <summary>
/// Gets items from the cache. For every key that is not found, a null value is returned.
/// </summary>
/// <param name="keys">Keys</param>
/// <returns>Cached items</returns>
object[] GetOrDefault(string[] keys);
/// <summary>
/// Gets an item from the cache or null if not found.
/// </summary>
/// <param name="key">Key</param>
/// <returns>Cached item or null if not found</returns>
Task<object> GetOrDefaultAsync(string key);
/// <summary>
/// Gets items from the cache. For every key that is not found, a null value is returned.
/// </summary>
/// <param name="keys">Keys</param>
/// <returns>Cached items</returns>
Task<object[]> GetOrDefaultAsync(string[] keys);
/// <summary>
/// Saves/Overrides an item in the cache by a key.
/// Use one of the expire times at most (<paramref name="slidingExpireTime"/> or <paramref name="absoluteExpireTime"/>).
/// If none of them is specified, then
/// <see cref="DefaultAbsoluteExpireTime"/> will be used if it's not null. Othewise, <see cref="DefaultSlidingExpireTime"/>
/// will be used.
/// </summary>
/// <param name="key">Key</param>
/// <param name="value">Value</param>
/// <param name="slidingExpireTime">Sliding expire time</param>
/// <param name="absoluteExpireTime">Absolute expire time</param>
void Set(string key, object value, TimeSpan? slidingExpireTime = null, TimeSpan? absoluteExpireTime = null);
/// <summary>
/// Saves/Overrides items in the cache by the pairs.
/// Use one of the expire times at most (<paramref name="slidingExpireTime"/> or <paramref name="absoluteExpireTime"/>).
/// If none of them is specified, then
/// <see cref="DefaultAbsoluteExpireTime"/> will be used if it's not null. Othewise, <see cref="DefaultSlidingExpireTime"/>
/// will be used.
/// </summary>
/// <param name="pairs">Pairs</param>
/// <param name="slidingExpireTime">Sliding expire time</param>
/// <param name="absoluteExpireTime">Absolute expire time</param>
void Set(KeyValuePair<string, object>[] pairs, TimeSpan? slidingExpireTime = null, TimeSpan? absoluteExpireTime = null);
/// <summary>
/// Saves/Overrides an item in the cache by a key.
/// Use one of the expire times at most (<paramref name="slidingExpireTime"/> or <paramref name="absoluteExpireTime"/>).
/// If none of them is specified, then
/// <see cref="DefaultAbsoluteExpireTime"/> will be used if it's not null. Othewise, <see cref="DefaultSlidingExpireTime"/>
/// will be used.
/// </summary>
/// <param name="key">Key</param>
/// <param name="value">Value</param>
/// <param name="slidingExpireTime">Sliding expire time</param>
/// <param name="absoluteExpireTime">Absolute expire time</param>
Task SetAsync(string key, object value, TimeSpan? slidingExpireTime = null, TimeSpan? absoluteExpireTime = null);
/// <summary>
/// Saves/Overrides items in the cache by the pairs.
/// Use one of the expire times at most (<paramref name="slidingExpireTime"/> or <paramref name="absoluteExpireTime"/>).
/// If none of them is specified, then
/// <see cref="DefaultAbsoluteExpireTime"/> will be used if it's not null. Othewise, <see cref="DefaultSlidingExpireTime"/>
/// will be used.
/// </summary>
/// <param name="pairs">Pairs</param>
/// <param name="slidingExpireTime">Sliding expire time</param>
/// <param name="absoluteExpireTime">Absolute expire time</param>
Task SetAsync(KeyValuePair<string, object>[] pairs, TimeSpan? slidingExpireTime = null, TimeSpan? absoluteExpireTime = null);
/// <summary>
/// Removes a cache item by it's key (does nothing if given key does not exists in the cache).
/// </summary>
/// <param name="key">Key</param>
void Remove(string key);
/// <summary>
/// Removes cache items by their keys.
/// </summary>
/// <param name="keys">Keys</param>
void Remove(string[] keys);
/// <summary>
/// Removes a cache item by it's key (does nothing if given key does not exists in the cache).
/// </summary>
/// <param name="key">Key</param>
Task RemoveAsync(string key);
/// <summary>
/// Removes cache items by their keys.
/// </summary>
/// <param name="keys">Keys</param>
Task RemoveAsync(string[] keys);
/// <summary>
/// Clears all items in this cache.
/// </summary>
void Clear();
/// <summary>
/// Clears all items in this cache.
/// </summary>
Task ClearAsync();
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment