[英]How would I configure ninject to use the base factory for all derived types of that class?
Given a base class in which we are supposed to use static factory methods to construct all derived classes, how would I bind such that derived types are created by the base factory? 给定一个我们应该使用静态工厂方法构造所有派生类的基类,我将如何绑定以便派生类型由该基工厂创建?
public abstract class BusinessObject<T> where T : BusinessObject<T>, new()
{
#region Member Variables
/// <summary>
/// Object that acts as a lock when retrieving or creating the singleton instance.
/// </summary>
private static object singletonLock = new object();
/// <summary>
/// Singleton instance of this business object with default connection string.
/// </summary>
private static T instance;
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#endregion Member Variables
#region Properties
/// <summary>
/// Gets the connection string.
/// </summary>
/// <value>The connection string.</value>
public virtual string ConnectionString { get; protected set; }
/// <summary>
/// Default connection string for business object.
/// </summary>
protected virtual string DefaultConnectionString { get { return ConfigurationManager.ConnectionStrings["LocalSqlConnection"].ConnectionString; } }
/// <summary>
/// Creates or retrieves the singleton instance of this business object.
/// </summary>
public static T Instance { get { return GetInstance(); } }
protected static log4net.ILog Log { get { return log; } }
#endregion Properties
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="BusinessObject"/> class.
/// </summary>
protected BusinessObject()
{
ConnectionString = DefaultConnectionString;
}
#endregion Constructor
#region Methods
/// <summary>
/// Returns singleton business object using default connection string.
/// </summary>
public static T GetInstance()
{
if (instance != null)
return instance;
// If instance has not been created, create new instance (with thread-safe lock).
lock (singletonLock)
{
if (instance == null)
instance = new T();
}
return instance;
}
/// <summary>
/// Returns new instance of business object using custom connection string.
/// </summary>
public static T GetInstance(string connectionString)
{
return new T() { ConnectionString = connectionString };
}
#endregion Methods
}
Sample snippet of derived class: 派生类的样本片段:
public class ProjectBO : BusinessObject<ProjectBO>
{
#region Constructors
[Obsolete("Use instance property instead", false)]
public ProjectBO() { }
static ProjectBO()
{
quotaGroupBlacklist = new List<int>();
unavailableQuotaGroupsByMember = new Dictionary<int, List<int>>();
unavailableProjectsByMember = new Dictionary<int, List<int>>();
}
#endregion Constructors
}
so I want to (by convention) hook up all derived types to use the base class factory method GetInstance(string)
所以我想(按照惯例)连接所有派生类型以使用基类工厂方法
GetInstance(string)
how can I do this without changing the base or derived classes? 如何在不更改基类或派生类的情况下做到这一点?
This is how you could do that: 这是您可以这样做的方式:
this.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(BusinessObject<>))
.BindWith<BusinessObjectBindingGenerator>());
public class BusinessObjectBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
yield return bindingRoot
.Bind(type)
.ToMethod(ctx => CreateBusinessObject(type));
}
private static object CreateBusinessObject(Type type)
{
return typeof(BusinessObject<>)
.MakeGenericType(type)
.GetMethod("GetInstance", BindingFlags.Static | BindingFlags.Public)
.Invoke(null, new object[0]);
}
}
Disclaimer: i didn't test the reflection stuff but i think it's correct. 免责声明:我没有测试反射的东西,但我认为这是正确的。
Also note that i think it's bad design. 另请注意,我认为这是不好的设计。 I think it's a bit smelly.
我觉得有点臭。
Why are you even using the .GetInstance
method? 为什么还要使用
.GetInstance
方法? You could just as easily replace it with: 您可以轻松地将其替换为:
this.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(BusinessObject<>))
.BindToSelf()
.Configure(x => x.InSingletonScope()));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.