vel*_*koz 33 c# parameters singleton arguments design-patterns
我需要一个单例类来实例化一些参数.我现在这样做的方式是:
class SingletonExample
{
private SingletonExample mInstance;
//other members...
private SingletonExample()
{
}
public SingletonExample Instance
{
get
{
if (mInstance == null)
{
throw new Exception("Object not created");
}
return mInstance;
}
}
public void Create(string arg1, string arg2)
{
mInstance = new SingletonExample();
mInstance.Arg1 = arg1;
mInstance.ObjectCaller = new ObjectCaller(arg2);
//etc... basically, create object...
}
}
Run Code Online (Sandbox Code Playgroud)
该实例是"迟到"创建的,这意味着我没有在app启动时获得所有必需的参数.
一般来说,我不喜欢强制方法调用的排序,但我在这里看不到另一种方式.IoC也不会解决它,因为我可以在容器中注册它,我也可以调用Create()...
你认为这是一个好的方案吗?你有其他想法吗?
编辑:我知道我写的一个例子,它不是线程安全的,线程安全不是问题的一部分
ann*_*ata 34
单身人士是丑陋的,但因为用户whateva无法纠正他自己的代码......
public class Singleton
{
private static Singleton _instance = null;
private static Object _mutex = new Object();
private Singleton(object arg1, object arg2)
{
// whatever
}
public static Singleton GetInstance(object arg1, object arg2)
{
if (_instance == null)
{
lock (_mutex) // now I can claim some form of thread safety...
{
if (_instance == null)
{
_instance = new Singleton(arg1, arg2);
}
}
}
return _instance;
}
}
Run Code Online (Sandbox Code Playgroud)
Skeet在几年前的博客中写道,我认为,它非常可靠.没有必要的例外,你不会记住什么对象应该是单身,并在你弄错时处理后果.
编辑:类型不相关使用你想要的,object这里只是为了方便起见.
Eri*_*ler 23
一个带有参数的单身人士对我来说有点腥味.
考虑whateva的答案和以下代码:
Singleton x = Singleton.getInstance("hello", "world");
Singleton y = Singleton.getInstance("foo", "bar");
Run Code Online (Sandbox Code Playgroud)
显然,x == y和y与x的创建参数一起使用,而y的创建参数则被简单地忽略.结果可能至少令人困惑.
如果你真的,真的像你必须这样做,就这样做:
class SingletonExample
{
private static SingletonExample mInstance;
//other members...
private SingletonExample()
{ // never used
throw new Exception("WTF, who called this constructor?!?");
}
private SingletonExample(string arg1, string arg2)
{
mInstance.Arg1 = arg1;
mInstance.ObjectCaller = new ObjectCaller(arg2);
//etc... basically, create object...
}
public static SingletonExample Instance
{
get
{
if (mInstance == null)
{
throw new Exception("Object not created");
}
return mInstance;
}
}
public static void Create(string arg1, string arg2)
{
if (mInstance != null)
{
throw new Exception("Object already created");
}
mInstance = new SingletonExample(arg1, arg2);
}
}
Run Code Online (Sandbox Code Playgroud)
在多线程环境中,添加同步以避免竞争条件.
更好的答案:
创建一个界面:( ISingleton包含你想做的任何动作)
而你的类型: Singleton : ISingleton
假设您有权访问UnityContainer:
IUnityContainer _singletonContainer = new UnityContainer(); // or whatever code to initialize the container
_singletonContainer.RegisterType(typeof(ISingleton), new Singleton(params));
var localSingletonVar = _singletonContainer.Resolve<ISingleton>();
注意:如果容器没有为ISingleton接口注册的类型,那么它应该抛出异常,或者返回null.
旧答案:
public class Singleton
{
private static Singleton instance = null;
private Singleton(String arg1, String arg2)
{
}
public static Singleton getInstance(String arg1, String arg2)
{
if (instance != null)
{
throw new InvalidOperationException("Singleton already created - use getinstance()");
}
instance = new Singleton(arg1, arg2);
return instance;
}
public static Singleton getInstance()
{
if (instance == null)
throw new InvalidOperationException("Singleton not created - use GetInstance(arg1, arg2)");
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
我会用类似的东西(你可能需要检查是否也创建了实例),或者,如果你的DI容器支持在非注册类型上抛出异常,我会继续使用它.
ATTN:非线程安全代码:)