Aracılığıyla paylaş


C# İfadeleri

.NET Framework 4.5'den başlayarak, C# ifadeleri Windows Workflow Foundation'da (WF) desteklenir. Visual Studio 2012'de oluşturulan ve .NET Framework 4.5'i hedefleyen yeni C# iş akışı projeleri C# ifadelerini, Visual Basic iş akışı projeleri ise Visual Basic ifadelerini kullanır. Visual Basic ifadelerini kullanan mevcut .NET Framework 4 iş akışı projeleri, proje dilinden bağımsız olarak .NET Framework 4.6.1'e geçirilebilir ve desteklenir. Bu konu, WF'deki C# ifadelerine genel bir bakış sağlar.

İş akışlarında C# ifadelerini kullanma

İş Akışı Tasarımcısı'nda C# ifadelerini kullanma

.NET Framework 4.5'den başlayarak, C# ifadeleri Windows Workflow Foundation'da (WF) desteklenir. Visual Studio 2012'de oluşturulan ve .NET Framework 4.5'i hedefleyen C# iş akışı projeleri C# ifadelerini, Visual Basic iş akışı projeleri ise Visual Basic ifadelerini kullanır. İstenen C# ifadesini belirtmek için, C# ifadesi girin etiketli kutuya yazın. Bu etiket, etkinlik tasarımcıda veya iş akışı tasarımcısındaki etkinlikte seçildiğinde özellikler penceresinde görüntülenir. Örnek olarak, iki WriteLine etkinlik, Sequence içindeki NoPersistScope'in içinde yer almaktadır.

Otomatik olarak oluşturulan bir sıra etkinliğini gösteren ekran görüntüsü.

Uyarı

C# ifadeleri yalnızca Visual Studio'da desteklenir ve yeniden barındırılan iş akışı tasarımcısında desteklenmez. Yeniden barındırılan tasarımcıda desteklenen yeni WF45 özellikleri hakkında daha fazla bilgi için bkz. Yeniden Barındırılan İş Akışı Tasarımcısı'nda Yeni Workflow Foundation 4.5 Özellikleri Desteği.

Geriye dönük uyumluluk

.NET Framework 4.6.1'e geçirilen mevcut .NET Framework 4 C# iş akışı projelerindeki Visual Basic ifadeleri desteklenir. Visual Basic ifadeleri iş akışı tasarımcısında görüntülendiğinde, Visual Basic ifadesi geçerli bir C# söz dizimi olmadığı sürece mevcut Visual Basic ifadesinin metni XAML'de Değer olarak ayarlanmış olarak değiştirilir. Visual Basic ifadesi geçerli bir C# söz dizimiyse, ifade görüntülenir. Visual Basic ifadelerini C# olarak güncelleştirmek için, bunları iş akışı tasarımcısında düzenleyebilir ve eşdeğer C# ifadesini belirtebilirsiniz. Visual Basic ifadelerinin C# olarak güncelleştirilmesi gerekmez, ancak iş akışı tasarımcısında ifadeler güncelleştirildikten sonra C# biçimine dönüştürülür ve Visual Basic'e geri döndürülmeyebilir.

Kod iş akışlarında C# ifadelerini kullanma

C# ifadeleri .NET Framework 4.6.1 kod tabanlı iş akışlarında desteklenir, ancak iş akışının çağrılabilmesi için C# ifadelerinin kullanılarak TextExpressionCompiler.Compilederlenmesi gerekir. İş akışı yazarları bir ifadenin r-değerini ve CSharpValue bir ifadenin l değerini temsil etmek için kullanabilirCSharpReference. Aşağıdaki örnekte, bir Assign etkinliği ve bir WriteLine etkinliğin içinde yer aldığı bir Sequence etkinliği içeren bir iş akışı oluşturulur. Bağımsız değişken CSharpReference için To belirli bir Assign belirtilmiş olup, ifadenin L-değerini temsil eder. CSharpValue ve Value bağımsız değişkenleri, Assign ile Text argümanları için belirtilir ve bu iki ifade için r-değerini temsil eder.

Variable<int> n = new Variable<int>
{
    Name = "n"
};

Activity wf = new Sequence
{
    Variables = { n },
    Activities =
    {
        new Assign<int>
        {
            To = new CSharpReference<int>("n"),
            Value = new CSharpValue<int>("new Random().Next(1, 101)")
        },
        new WriteLine
        {
            Text = new CSharpValue<string>("\"The number is \" + n")
        }
    }
};

CompileExpressions(wf);

WorkflowInvoker.Invoke(wf);

İş akışı oluşturulduktan sonra, yardımcı yöntem çağrılarak C# ifadeleri derlenir ve ardından iş akışı çağrılır. Aşağıdaki örnek yöntemidir CompileExpressions .

static void CompileExpressions(Activity activity)
{
    // activityName is the Namespace.Type of the activity that contains the
    // C# expressions.
    string activityName = activity.GetType().ToString();

    // Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
    // to represent the new type that represents the compiled expressions.
    // Take everything after the last . for the type name.
    string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
    // Take everything before the last . for the namespace.
    string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());

    // Create a TextExpressionCompilerSettings.
    TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
    {
        Activity = activity,
        Language = "C#",
        ActivityName = activityType,
        ActivityNamespace = activityNamespace,
        RootNamespace = null,
        GenerateAsPartialClass = false,
        AlwaysGenerateSource = true,
        ForImplementation = false
    };

    // Compile the C# expression.
    TextExpressionCompilerResults results =
        new TextExpressionCompiler(settings).Compile();

    // Any compilation errors are contained in the CompilerMessages.
    if (results.HasErrors)
    {
        throw new Exception("Compilation failed.");
    }

    // Create an instance of the new compiled expression type.
    ICompiledExpressionRoot compiledExpressionRoot =
        Activator.CreateInstance(results.ResultType,
            new object[] { activity }) as ICompiledExpressionRoot;

    // Attach it to the activity.
    CompiledExpressionInvoker.SetCompiledExpressionRoot(
        activity, compiledExpressionRoot);
}

Uyarı

C# ifadeleri derlenmiyorsa, iş akışı aşağıdakine benzer bir iletiyle çağrıldığında bir NotSupportedException oluşturulur: Expression Activity type 'CSharpValue1' çalıştırmak için derleme gerektirir. Lütfen iş akışının derlendiğinden emin olun.'

Özel kod tabanlı iş akışınız DynamicActivity kullanıyorsa, aşağıdaki kod örneğinde gösterildiği gibi CompileExpressions yönteminde bazı değişiklikler yapılması gerekmektedir.

static void CompileExpressions(DynamicActivity dynamicActivity)
{
    // activityName is the Namespace.Type of the activity that contains the
    // C# expressions. For Dynamic Activities this can be retrieved using the
    // name property , which must be in the form Namespace.Type.
    string activityName = dynamicActivity.Name;

    // Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
    // to represent the new type that represents the compiled expressions.
    // Take everything after the last . for the type name.
    string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
    // Take everything before the last . for the namespace.
    string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());

    // Create a TextExpressionCompilerSettings.
    TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
    {
        Activity = dynamicActivity,
        Language = "C#",
        ActivityName = activityType,
        ActivityNamespace = activityNamespace,
        RootNamespace = null,
        GenerateAsPartialClass = false,
        AlwaysGenerateSource = true,
        ForImplementation = true
    };

    // Compile the C# expression.
    TextExpressionCompilerResults results =
        new TextExpressionCompiler(settings).Compile();

    // Any compilation errors are contained in the CompilerMessages.
    if (results.HasErrors)
    {
        throw new Exception("Compilation failed.");
    }

    // Create an instance of the new compiled expression type.
    ICompiledExpressionRoot compiledExpressionRoot =
        Activator.CreateInstance(results.ResultType,
            new object[] { dynamicActivity }) as ICompiledExpressionRoot;

    // Attach it to the activity.
    CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation(
        dynamicActivity, compiledExpressionRoot);
}

Bir dinamik etkinlikte CompileExpressions C# ifadelerini derleyen aşırı yüklemede çeşitli farklılıklar vardır.

  • CompileExpressions'a ait olan parametre bir DynamicActivity'dir.

  • Tür adı ve ad alanı DynamicActivity.Name özelliği kullanılarak elde edilir.

  • TextExpressionCompilerSettings.ForImplementation olarak ayarlanır true.

  • CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation yerine çağrılır CompiledExpressionInvoker.SetCompiledExpressionRoot.

Koddaki ifadelerle çalışma hakkında daha fazla bilgi için bkz. Kesinlik Temelli Kod Kullanarak İş Akışları, Etkinlikler ve İfadeler Yazma.

XAML iş akışlarında C# ifadelerini kullanma

C# ifadeleri XAML iş akışlarında desteklenir. Derlenen XAML iş akışları bir türe derlenir ve gevşek XAML iş akışları çalışma zamanı tarafından yüklenir ve iş akışı yürütülürken bir etkinlik ağacına derlenir.

Derlenmiş Xaml

C# ifadeleri, .NET Framework 4.6.1'i hedefleyen bir C# iş akışı projesinin parçası olarak bir türe derlenen derlenmiş XAML iş akışlarında desteklenir. Derlenmiş XAML, Visual Studio'da varsayılan iş akışı yazma türüdür ve Visual Studio'da oluşturulan ve .NET Framework 4.6.1'i hedefleyen C# iş akışı projeleri C# ifadelerini kullanır.

Gevşek Xaml

C# ifadeleri gevşek XAML iş akışlarında desteklenir. Gevşek XAML iş akışını yükleyen ve çağıran iş akışı konak programı .NET Framework 4.6.1'i hedeflemeli ve CompileExpressions olarak ayarlanmalıdır true (varsayılan değerdir false). CompileExpressions ayarlamak için, true özelliği ActivityXamlServicesSettings olarak ayarlanmış bir CompileExpressions örneği oluşturun ve bunu true parametresi olarak geçirin. CompileExpressions, true olarak ayarlanmadığında, aşağıdakine benzer bir mesajla NotSupportedException oluşturulur: Expression Activity type 'CSharpValue1' öğesinin çalışması için derleme gerekir. Lütfen iş akışının derlendiğinden emin olun.'

ActivityXamlServicesSettings settings = new ActivityXamlServicesSettings
{
    CompileExpressions = true
};

DynamicActivity<int> wf = ActivityXamlServices.Load(new StringReader(serializedAB), settings) as DynamicActivity<int>;

XAML iş akışlarıyla çalışma hakkında daha fazla bilgi için bkz. XAML'ye ve XAML'den İş Akışlarını ve Etkinlikleri SeriLeştirme.

XAMLX iş akışı hizmetlerinde C# ifadelerini kullanma

C# ifadeleri XAMLX iş akışı hizmetlerinde desteklenir. Bir iş akışı hizmeti IIS veya WAS içinde barındırıldığında ek adım gerekmez, ancak XAML iş akışı hizmeti şirket içinde barındırılıyorsa C# ifadelerinin derlenmiş olması gerekir. Kendi içinde barındırılan bir XAMLX iş akışı hizmetinde C# ifadelerini derlemek için, önce XAMLX dosyasını WorkflowService içine yükleyin ve ardından BodyWorkflowService öğesini, önceki CompileExpressions bölümünde açıklanan yöntemine iletin. Aşağıdaki örnekte bir XAMLX iş akışı hizmeti yüklenir, C# ifadeleri derlenir ve ardından iş akışı hizmeti açılır ve istekleri bekler.

// Load the XAMLX workflow service.
WorkflowService workflow1 =
    (WorkflowService)XamlServices.Load(xamlxPath);

// Compile the C# expressions in the workflow by passing the Body to CompileExpressions.
CompileExpressions(workflow1.Body);

// Initialize the WorkflowServiceHost.
var host = new WorkflowServiceHost(workflow1, new Uri("http://localhost:8293/Service1.xamlx"));

// Enable Metadata publishing/
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);

// Open the WorkflowServiceHost and wait for requests.
host.Open();
Console.WriteLine("Press enter to quit");
Console.ReadLine();

C# ifadeleri derlenmiyorsa işlem Open başarılı olur, ancak iş akışı çağrıldığında başarısız olur. Aşağıdaki CompileExpressions yöntem, kod iş akışlarında C# ifadelerini kullanma bölümündeki yöntemle aynıdır.

static void CompileExpressions(Activity activity)
{
    // activityName is the Namespace.Type of the activity that contains the
    // C# expressions.
    string activityName = activity.GetType().ToString();

    // Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
    // to represent the new type that represents the compiled expressions.
    // Take everything after the last . for the type name.
    string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
    // Take everything before the last . for the namespace.
    string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());

    // Create a TextExpressionCompilerSettings.
    TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
    {
        Activity = activity,
        Language = "C#",
        ActivityName = activityType,
        ActivityNamespace = activityNamespace,
        RootNamespace = null,
        GenerateAsPartialClass = false,
        AlwaysGenerateSource = true,
        ForImplementation = false
    };

    // Compile the C# expression.
    TextExpressionCompilerResults results =
        new TextExpressionCompiler(settings).Compile();

    // Any compilation errors are contained in the CompilerMessages.
    if (results.HasErrors)
    {
        throw new Exception("Compilation failed.");
    }

    // Create an instance of the new compiled expression type.
    ICompiledExpressionRoot compiledExpressionRoot =
        Activator.CreateInstance(results.ResultType,
            new object[] { activity }) as ICompiledExpressionRoot;

    // Attach it to the activity.
    CompiledExpressionInvoker.SetCompiledExpressionRoot(
        activity, compiledExpressionRoot);
}