C# 防止类在此类之外实例化
我使用C# 防止类在此类之外实例化,c#,entity-framework,oop,C#,Entity Framework,Oop,我使用entityframework和为DbContext生成的类。生成这些类,并且在下次刷新DbContext时,我所做的每个更改都会被覆盖 现在我重写这个类来动态生成到数据库的连接,这很好。但问题是,您也可以使用无参数构造函数创建类,如果连接不是动态的,这将导致大问题。 有没有办法禁止在生成的类之外使用无参数构造函数实例化生成的类 例如: 生成的不带参数的类: public partial class SomeConnection : DbContext { public SomeC
entityframework
和为DbContext
生成的类。生成这些类,并且在下次刷新DbContext
时,我所做的每个更改都会被覆盖
现在我重写这个类来动态生成到数据库的连接,这很好。但问题是,您也可以使用无参数构造函数创建类,如果连接不是动态的,这将导致大问题。有没有办法禁止在生成的类之外使用无参数构造函数实例化生成的类 例如:
生成的不带参数的类:
public partial class SomeConnection : DbContext
{
public SomeConnection()
: base("name=myWrongConnection")
{
//should not be able to be called!
}
// some more generated and needed stuff!
...
}
这里是我需要实例化的类:
public partial class SomeConnection
{
public SomeConnection(String connectionString)
: base(connectionString)
{
// only this constructor should be called without changing the parent class...
}
}
最好使用工厂,但如果您绝对需要禁止使用错误的实例,则可能的解决方法是重写ModelCreating上的
,
,因此即使使用错误的构造函数创建实例,也无法使用该实例:
public partial class SomeConnection
{
private readonly bool correctConstructorWasCalled;
public DerivedContext(string connectionString)
:base(connectionString)
{
correctConstructorWasCalled = true;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (!correctConstructorWasCalled)
{
throw new InvalidOperationException("Please call the correct constructor.");
}
base.OnModelCreating(modelBuilder);
}
}
public class Guard
{
public Guard([CallerMemberName] string callerName = null)
{
var constructorExpression = (Expression<Func<Prohibited>>)(() => new Prohibited());
var constructorMethod = (NewExpression) (constructorExpression.Body);
var stackFrames = new StackTrace().GetFrames();
if (stackFrames.Any(f => f.GetMethod() == constructorMethod.Constructor))
{
throw new InvalidOperationException("Aha! you are still trying.");
}
}
}
public partial class Prohibited : DbContext
{
public Prohibited()
: base("wrong connection string")
{
}
}
public partial class Prohibited
{
private Guard guard = new Guard();
public Prohibited(string connectionString)
: base(connectionString)
{
}
}
更新:
我找到了一个绝对拒绝特定构造函数的解决方案:
public partial class SomeConnection
{
private readonly bool correctConstructorWasCalled;
public DerivedContext(string connectionString)
:base(connectionString)
{
correctConstructorWasCalled = true;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (!correctConstructorWasCalled)
{
throw new InvalidOperationException("Please call the correct constructor.");
}
base.OnModelCreating(modelBuilder);
}
}
public class Guard
{
public Guard([CallerMemberName] string callerName = null)
{
var constructorExpression = (Expression<Func<Prohibited>>)(() => new Prohibited());
var constructorMethod = (NewExpression) (constructorExpression.Body);
var stackFrames = new StackTrace().GetFrames();
if (stackFrames.Any(f => f.GetMethod() == constructorMethod.Constructor))
{
throw new InvalidOperationException("Aha! you are still trying.");
}
}
}
public partial class Prohibited : DbContext
{
public Prohibited()
: base("wrong connection string")
{
}
}
public partial class Prohibited
{
private Guard guard = new Guard();
public Prohibited(string connectionString)
: base(connectionString)
{
}
}
公共类保护
{
公共保护([CallerMemberName]字符串callerName=null)
{
var-constructorExpression=(表达式)(()=>new-instructed());
var constructorMethod=(NewExpression)(constructorExpression.Body);
var stackFrames=new StackTrace().GetFrames();
if(stackFrames.Any(f=>f.GetMethod()==constructorMethod.Constructor))
{
抛出新的InvalidOperationException(“啊哈!你还在尝试。”);
}
}
}
禁止使用公共部分类:DbContext
{
公众禁止()
:base(“错误的连接字符串”)
{
}
}
禁止公共部分课程
{
私人警卫=新警卫();
公共禁止(字符串连接字符串)
:基本(连接字符串)
{
}
}
[CallerMemberName]
是必需的,因此在发布配置中不会优化调用方框架。关于抽象
基类如何?不可能像前面提到的那样更改基类!已生成此类。是否可以为此类创建包装类,然后将包装类设置为单例类?是否可以访问连接字符串?此处的术语错误,您不能将部分类称为父类/子类。解决方法不错。但我的意图是甚至不提供它来调用这个构造函数。