मैं एक wpf एप्लिकेशन पर कमांड हैंडलर पैटर्न लागू करने का प्रयास कर रहा हूं।

मुझे इस तरह की कार्यक्षमता रखने के लिए आईओसी कंटेनर (मेरे मामले में मैं साधारण इंजेक्टर का उपयोग करता हूं) को कॉन्फ़िगर करने के तरीके को समझने में कुछ समस्या है।

मैं एक डेटाबेस कमांड हैंडलर निष्पादित करना चाहता हूं (जो DbContext पर कुछ ऑपरेशन निष्पादित करता है) और प्रत्येक कमांड को उसी संदर्भ में बनाए गए लेनदेन के अंदर लपेटना होगा।

कुछ इस तरह (यह सिर्फ एक उदाहरण है)


public class BusinessUseCases
{
    public void BusinessCase1()
    {
        BusinessCommandParams1 commandParams = new BusinessCommandParams1();

        using (var db = new DbContext(connectionString))
        {
            IDatabaseCommand<DatabaseResult, BusinessCommandParams1> databaseCreate =
                new TransactionDatabaseCommandDecorator(new BusinessCommand(db), db);

            databaseCreate.Execute(commandParams);
        }
    }

    ....

    Other business case
}

public interface IDatabaseCommand<TResult, TParam>
{
    TResult Execute(TParam commandParam);
}

public class BusinessCommandParams1
{
    //some property
}

public class DatabaseResult
{
    //some property
}
public class BusinessCommand : IDatabaseCommand<DatabaseResult, BusinessCommandParams1>
{
    private readonly DbContext _context;

    public BusinessCommand(IDbContext context)
    {
        _context = context;
    }

    public DatabaseResult Execute(BusinessCommandParams1 commandParam)
    {
        //use context
        return new DatabaseResult();
    }
}

public class TransactionDatabaseCommandDecorator : IDatabaseCommand<DatabaseResult, BusinessCommandParams1>
{
    private readonly IDatabaseCommand<DatabaseResult, BusinessCommandParams1> _command;
    private readonly DbContext _context;

    public TransactionDatabaseCommandDecorator(IDatabaseCommand<DatabaseResult, BusinessCommandParams1> command, DbContext context)
    {
        _command = command;
        _context = context;
    }

    public DatabaseResult Execute(BusinessCommandParams1 commandParam)
    {
        using (var transaction = _context.Database.BeginTransaction())
        {
            try
            {
                _command.Execute(commandParam);
                transaction.Commit();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                transaction.Discard();
                throw;
            }
        }
    }
}

तो मूल रूप से मुझे POOR MAN DI . का उपयोग करके ऐसा कुछ लागू करने की आवश्यकता है

public class BusinessUseCases
{
    public void BusinessCase1()
    {
        BusinessCommandParams1 commandParams = new BusinessCommandParams1();


        using (var db = new DbContext(connectionString))
        {
            IDatabaseCommand<DatabaseResult, BusinessCommandParams1> databaseCreate =
                new TransactionDatabaseCommandDecorator(new BusinessCommand(db), db);

            databaseCreate.Execute(commandParams);
        }
    }

    ....

    Other business case
}

साधारण इंजेक्टर या किसी अन्य आईओसी कंटेनर के साथ।

मुझे इसकी आवश्यकता है कि कमांड हैंडलर को एक सिंगल स्कॉप्ड डीबीकॉन्टेक्स्ट के अंदर लिपटे बिजनेस केस लॉजिक के साथ लागू करें। बेहतर ढंग से समझाने के लिए मुझे कंटेनर से सही कमांड हैंडलर प्राप्त करने की आवश्यकता है जो एक अच्छी तरह से परिभाषित डीबीकॉन्टेक्स्ट के अंदर अपने तर्क को निष्पादित करता है जिसे निष्पादन के बाद निपटाया जा रहा है।

लेकिन मुझे समझ में नहीं आता कि आईओसी कंटेनर में सभी वर्गों को पंजीकृत करके इसे कैसे पूरा किया जाए। हो सकता है कि मेरे कमांड हैंडलर डिज़ाइन या DI के उपयोग में कुछ गड़बड़ हो।

क्या आप कृपया मुझे कुछ उदाहरण दे सकते हैं या मुझे सही तरीके से चला सकते हैं?

अग्रिम में धन्यवाद

0
Federico Borghesi 2 अक्टूबर 2020, 18:36

1 उत्तर

सबसे बढ़िया उत्तर

सिंपल इंजेक्टर आपके कमांड हैंडलर जैसे सामान्य प्रकारों के ऑटो-पंजीकरण की अनुमति देता है। Container.Register पर एक ही कॉल से आपके सभी कमांड हैंडलर का पंजीकरण किया जा सकता है:

container.Register(typeof(IDatabaseCommand<,>), typeof(BusinessCommand).Assembly);

उसके बाद, आप अपने सज्जाकारों को एक-एक करके पंजीकृत कर सकते हैं:

container.RegisterDecorator(
    typeof(IDatabaseCommand<,>),
    typeof(TransactionDatabaseCommandDecorator));

ध्यान दें कि ऐसा डेकोरेटर सबसे अच्छा काम करता है जब यह एक सामान्य प्रकार होता है, क्योंकि उस स्थिति में, साधारण इंजेक्टर इसे किसी भी मनमाने IDatabaseCommand<,> कार्यान्वयन के आसपास लपेट सकता है।

सामान्य प्रकारों और सज्जाकारों को पंजीकृत करने के बारे में अधिक जानकारी के लिए, हमारे बढ़िया दस्तावेज़ पढ़ें:

0
Steven 2 अक्टूबर 2020, 19:39