Заводской инициализатор + синглтон - PullRequest
0 голосов
/ 13 ноября 2010

Я написал нестатический экземпляр класса Generic для своего проекта Abstract Factory и использую подход Singleton, чтобы гарантировать, что только 1 экземпляр экземпляра будет инициализирован для каждого клиентского запроса.Абстрагирование всего пространства имен для каждого Клиентапроблемы многопоточности (afaik, экземпляр singleton будет доступен всем клиентам).Я также буду признателен за любой другой подход к этому.спасибо

Ответы [ 3 ]

1 голос
/ 13 ноября 2010

У вас не будет проблем с многопоточностью, поскольку вы каждый раз создаете новый экземпляр.

О спектакле. Вы можете измерить время, создав 100 экземпляров:

long ini = Environment.TickCount;
for (int i = 0; i < 100; i++)
{
    Session["ClientCode"] = "Client2";
    clientInvoice = FactoryInstantiator<InvoiceFactory>.Instance.CreateInstance();
    clientInvoice.Set();
}
long timeCreate100Instances = Environment.TickCount - ini;

При использовании reflection снижение производительности происходит при загрузке сборки. Я думаю, что в вашем случае загружаемый вами класс находится в той же dll, вы также не будете экспериментировать с какой-либо проблемой производительности.

В другом случае вы можете кэшировать объекты Assembly в Hastable/Dictionary в вашем методе CreateInstance().

0 голосов
/ 13 ноября 2010

Загрузка сборок в состоянии сеанса для решения проблемы многопоточности.

   public T CreateInstance()
    {
        string fullClassName = typeof(T).ToString();
        string[] splitClassName = fullClassName.Split('.');
        _className = splitClassName[2];
        _assemblyName = splitClassName[0] + "." + _client + "." + splitClassName[1];
        _fullyQualifiedClassName = _assemblyName + "." + _className;


        T obj;
        var assemblies = HttpContext.Current.Session["ASSEMBLIES"] as Dictionary<string, T>;

        if (assemblies == null)
        {
            assemblies = new Dictionary<string, T>();
            assemblies.Add(_fullyQualifiedClassName, null);
            HttpContext.Current.Session.Add("ASSEMBLIES", assemblies);
        }

        obj = assemblies[_fullyQualifiedClassName] as T;

        if (obj == null)
        {
            obj = (T)Activator.CreateInstance(Type.GetType(_fullyQualifiedClassName + "," + _assemblyName));
            assemblies[_fullyQualifiedClassName] = obj;
        }



        return obj;
    }
0 голосов
/ 13 ноября 2010

Используя предложения Ричарда и Даниэля, я смог снизить производительность отражения с помощью кэширования. Поэтому я делаю вывод, что у Reflection действительно есть огромные проблемы с производительностью.

  public T CreateInstance()
    {
        string fullClassName = typeof(T).ToString();
        string[] splitClassName = fullClassName.Split('.');
        _className = splitClassName[2];
        _assemblyName = splitClassName[0] + "." + _client + "." + splitClassName[1];
        _fullyQualifiedClassName = _assemblyName + "." + _className;

        // use caching
        T obj;
        if (HttpContext.Current.Cache[_fullyQualifiedClassName] == null)
        {
            obj = (T)Activator.CreateInstance(Type.GetType(_fullyQualifiedClassName + "," + _assemblyName));
            HttpContext.Current.Cache.Insert(_fullyQualifiedClassName, obj, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero);
        }
        else
        {
            obj = (T)HttpContext.Current.Cache[_fullyQualifiedClassName];
        }

        return obj;
    }


protected void Page_Load(object sender, EventArgs e)
{
    InvoiceFactory inv;

    Stopwatch globalTimer = Stopwatch.StartNew();

    //normal instantiation
    globalTimer = Stopwatch.StartNew();
    for (int x = 0; x <= 10000; x++)
        inv = new InventorySuit.Client1.BusinessLogic.Invoice;
    globalTimer.Stop();
    Response.Write(globalTimer.ElapsedMilliseconds + "<BR>");
    //result 0ms


    // using singleton factory w/o caching
    globalTimer = Stopwatch.StartNew();
    for (int x = 0; x <= 10000; x++)
        inv = new FactoryInstantiator<InvoiceFactory>().CreateInstance();
    globalTimer.Stop();
    Response.Write(globalTimer.ElapsedMilliseconds + "<BR>");
    //result 129ms

    // using singleton factory w/ caching
    for (int x = 0; x <= 10000; x++)
        inv = FactoryInstantiator<InvoiceFactory>.Instance.CreateInstance();
    globalTimer.Stop();
    Response.Write(globalTimer.ElapsedMilliseconds + "<BR>");
    //result 21ms



}
...