Rychlé zprovoznění: Vytvoření datové továrny a kanálu pomocí sady .NET SDK
PLATÍ PRO: Azure Data Factory Azure Synapse Analytics
Tip
Vyzkoušejte si službu Data Factory v Microsoft Fabric, řešení pro analýzy typu all-in-one pro podniky. Microsoft Fabric zahrnuje všechno od přesunu dat až po datové vědy, analýzy v reálném čase, business intelligence a vytváření sestav. Přečtěte si, jak začít používat novou zkušební verzi zdarma.
Tento rychlý start popisuje, jak pomocí sady .NET SDK vytvořit službu Azure Data Factory. Kanál, který vytvoříte v této datové továrně, kopíruje data z jedné složky do jiné složky v úložišti objektů blob Azure. Kurz předvádějící způsoby transformace dat pomocí Azure Data Factory najdete v tématu Kurz: Transformace dat pomocí Sparku.
Poznámka:
Tento článek neposkytuje podrobný úvod do služby Data Factory. Úvod do služby Azure Data Factory najdete v tématu Úvod do Azure Data Factory.
Požadavky
Předplatné Azure
Pokud ještě nemáte předplatné Azure, vytvořte si napřed bezplatný účet.
Role Azure
Pro vytvoření instancí služby Data Factory musí být uživatelský účet, který použijete pro přihlášení k Azure, členem role přispěvatel nebo vlastník nebo správcem předplatného Azure. Pokud chcete zobrazit oprávnění, která máte v předplatném, přejděte na web Azure Portal, vyberte své uživatelské jméno v pravém horním rohu, vyberte ikonu ..., kde najdete další možnosti, a pak vyberte Moje oprávnění. Pokud máte přístup k několika předplatným, vyberte odpovídající předplatné.
Při vytváření a správě podřízených prostředků pro službu Data Factory, včetně datových sad, propojených služeb, kanálů, triggerů a prostředí Integration Runtime, platí následující požadavky:
- Pokud chcete vytvářet a spravovat podřízené prostředky na webu Azure Portal, je potřeba, abyste patřili do role Přispěvatel Data Factory na úrovni skupiny prostředků nebo vyšší.
- Pro vytváření a správu podřízených prostředků pomocí PowerShellu nebo sady SDK na úrovni prostředku nebo vyšší je dostatečná role Přispěvatel.
Ukázku pokynů pro přidání uživatele do role najdete v článku věnovaném přidávání rolí.
Další informace najdete v následujících článcích:
Účet služby Azure Storage
Jako zdrojové i cílové úložiště dat v tomto rychlém startu použijete účet služby Azure Storage pro obecné účely (konkrétně úložiště objektů blob). Pokud nemáte účet Azure Storage pro obecné účely, přečtěte si téma Vytvoření účtu úložiště, abyste ho vytvořili.
Získání názvu účtu úložiště
Pro účely tohoto rychlého startu potřebujete název účtu služby Azure Storage. Následující postup obsahuje postup získání názvu účtu úložiště:
- Ve webovém prohlížeči přejděte na web Azure Portal a přihlaste se pomocí uživatelského jména a hesla Azure.
- V nabídce webu Azure Portal vyberte Všechny služby a pak vyberte Účty úložiště úložiště>. Můžete také vyhledat a vybrat účty úložiště z libovolné stránky.
- Na stránce Účty úložiště vyfiltrujte svůj účet úložiště (v případě potřeby) a pak vyberte svůj účet úložiště.
Můžete také vyhledat a vybrat účty úložiště z libovolné stránky.
Vytvoření kontejneru objektů blob
V této části vytvoříte v úložišti objektů blob v Azure kontejner objektů blob s názvem adftutorial.
Na stránce účtu úložiště vyberte Přehled>kontejnerů.
Na panelu <nástrojů na stránce Kontejnery názvu - >účtu vyberte Kontejner.
V dialogovém okně Nový kontejner jako název zadejte adftutorial a pak vyberte OK. Stránka Kontejnery názvů - >účtů se aktualizuje tak, aby zahrnovala adftutorial v seznamu kontejnerů.<
Přidání vstupní složky a souboru pro kontejner objektů blob
V této části vytvoříte složku s názvem vstup v kontejneru, který jste vytvořili, a pak nahrajete ukázkový soubor do vstupní složky. Než začnete, otevřete textový editor, například Poznámkový blok, a vytvořte soubor s názvem emp.txt s následujícím obsahem:
John, Doe
Jane, Doe
Uložte soubor do složky C:\ADFv2QuickStartPSH . (Pokud složka ještě neexistuje, vytvořte ji.) Pak se vraťte na web Azure Portal a postupujte takto:
<Na stránce Kontejnery s názvem - >účtu, kde jste skončili, vyberte z aktualizovaného seznamu kontejnerů adftutorial.
- Pokud jste okno zavřeli nebo jste přešli na jinou stránku, znovu se přihlaste k webu Azure Portal .
- V nabídce webu Azure Portal vyberte Všechny služby a pak vyberte Účty úložiště úložiště>. Můžete také vyhledat a vybrat účty úložiště z libovolné stránky.
- Vyberte svůj účet úložiště a pak vyberte Kontejnery>adftutorial.
Na panelu nástrojů stránky kontejneru adftutorial vyberte Nahrát.
Na stránce Nahrát objekt blob vyberte pole Soubory a pak přejděte k souboru emp.txt a vyberte ho.
Rozbalte nadpis Upřesnit. Stránka se teď zobrazí takto:
Do pole Nahrát do složky zadejte vstup.
vyberte tlačítko Nahrát. Měli byste vidět soubor emp.txt a stav nahrávání v seznamu.
Výběrem ikony Zavřít (X) zavřete stránku Nahrát objekt blob.
Nechte stránku kontejneru adftutorial otevřenou. Použijete ji k ověření výstupu na konci tohoto rychlého startu.
Visual Studio
Návod v tomto článku používá Visual Studio 2019. Postupy pro Visual Studio 2013, 2015 nebo 2017 se mírně liší.
Vytvoření aplikace v Microsoft Entra ID
V částech Postupy : Použití portálu k vytvoření aplikace Microsoft Entra a instančního objektu, který má přístup k prostředkům, postupujte podle pokynů k těmto úlohám:
- V části Vytvoření aplikace Microsoft Entra vytvořte aplikaci, která představuje aplikaci .NET, kterou vytváříte v tomto kurzu. Jako přihlašovací adresu URL můžete poskytnout fiktivní URL, jak ukazuje článek (
https://contoso.org/exampleapp
). - V části Získání hodnot pro přihlášení získejte ID aplikace a ID tenanta a poznamenejte si tyto hodnoty, které použijete později v tomto kurzu.
- V certifikátech a tajných klíčích získejte ověřovací klíč a poznamenejte si tuto hodnotu, kterou použijete později v tomto kurzu.
- V části Přiřadit aplikaci k roli přiřaďte aplikaci roli Přispěvatel na úrovni předplatného, aby aplikace v předplatném vytvořila datové továrny.
Vytvoření projektu ve Visual Studiu
Dále v sadě Visual Studio vytvořte konzolovou aplikaci C#.NET:
- Spusťte Visual Studio.
- V okně Start vyberte Vytvořit novou konzolovou aplikaci projektu>(.NET Framework). Vyžaduje se .NET verze 4.5.2 nebo novější.
- V názvu projektu zadejte ADFv2QuickStart.
- Vyberte Vytvořit a vytvořte projekt.
Instalace balíčků NuGet
Vyberte nástroje>NuGet Správce balíčků> Správce balíčků konzoly.
V podokně konzoly Správce balíčků spusťte následující příkazy pro instalaci balíčků. Další informace najdete v balíčku NuGet Azure.ResourceManager.DataFactory .
Install-Package Azure.ResourceManager.DataFactory -IncludePrerelease Install-Package Azure.Identity
Vytvoření datové továrny
Otevřete soubor Program.cs a vložte do něj následující příkazy. Přidáte tak odkazy na obory názvů.
using Azure; using Azure.Core; using Azure.Core.Expressions.DataFactory; using Azure.Identity; using Azure.ResourceManager; using Azure.ResourceManager.DataFactory; using Azure.ResourceManager.DataFactory.Models; using Azure.ResourceManager.Resources; using System; using System.Collections.Generic;
Do metody Main přidejte následující kód, který nastaví proměnné. Zástupné znaky nahraďte vlastními hodnotami. Pokud chcete zobrazit seznam oblastí Azure, ve kterých je služba Data Factory aktuálně dostupná, na následující stránce vyberte oblasti, které vás zajímají, pak rozbalte Analýza a vyhledejte Data Factory:Dostupné produkty v jednotlivých oblastech. Úložiště dat (Azure Storage, Azure SQL Database a další) a výpočetní prostředí (HDInsight a další) používaná datovou továrnou můžou být v jiných oblastech.
// Set variables string tenantID = "<your tenant ID>"; string applicationId = "<your application ID>"; string authenticationKey = "<your authentication key for the application>"; string subscriptionId = "<your subscription ID where the data factory resides>"; string resourceGroup = "<your resource group where the data factory resides>"; string region = "<the location of your resource group>"; string dataFactoryName = "<specify the name of data factory to create. It must be globally unique.>"; string storageAccountName = "<your storage account name to copy data>"; string storageKey = "<your storage account key>"; // specify the container and input folder from which all files // need to be copied to the output folder. string inputBlobContainer = "<blob container to copy data from, e.g. containername>"; string inputBlobPath = "<path to existing blob(s) to copy data from, e.g. inputdir/file>"; //specify the contains and output folder where the files are copied string outputBlobContainer = "<blob container to copy data from, e.g. containername>"; string outputBlobPath = "<the blob path to copy data to, e.g. outputdir/file>"; // name of the Azure Storage linked service, blob dataset, and the pipeline string storageLinkedServiceName = "AzureStorageLinkedService"; string blobDatasetName = "BlobDataset"; string pipelineName = "Adfv2QuickStartPipeline";
Do metody Main přidejte následující kód, který vytvoří datovou továrnu.
ArmClient armClient = new ArmClient( new ClientSecretCredential(tenantID, applicationId, authenticationKey, new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }), subscriptionId, new ArmClientOptions { Environment = ArmEnvironment.AzurePublicCloud } ); ResourceIdentifier resourceIdentifier = SubscriptionResource.CreateResourceIdentifier(subscriptionId); SubscriptionResource subscriptionResource = armClient.GetSubscriptionResource(resourceIdentifier); Console.WriteLine("Get an existing resource group " + resourceGroupName + "..."); var resourceGroupOperation = subscriptionResource.GetResourceGroups().Get(resourceGroupName); ResourceGroupResource resourceGroupResource = resourceGroupOperation.Value; Console.WriteLine("Create a data factory " + dataFactoryName + "..."); DataFactoryData dataFactoryData = new DataFactoryData(AzureLocation.EastUS2); var dataFactoryOperation = resourceGroupResource.GetDataFactories().CreateOrUpdate(WaitUntil.Completed, dataFactoryName, dataFactoryData); Console.WriteLine(dataFactoryOperation.WaitForCompletionResponse().Content); // Get the data factory resource DataFactoryResource dataFactoryResource = dataFactoryOperation.Value;
Vytvoření propojené služby
Do metody Main přidejte následující kód, který vytvoří propojenou službu Azure Storage.
V datové továrně vytvoříte propojené služby, abyste svá úložiště dat a výpočetní služby spojili s datovou továrnou. V tomto rychlém startu potřebujete vytvořit pouze jednu propojenou službu Azure Blob Storage pro zdroj kopírování i úložiště jímky. v ukázce se jmenuje AzureBlobStorageLinkedService.
// Create an Azure Storage linked service
Console.WriteLine("Create a linked service " + storageLinkedServiceName + "...");
AzureBlobStorageLinkedService azureBlobStorage = new AzureBlobStorageLinkedService()
{
ConnectionString = azureBlobStorageConnectionString
};
DataFactoryLinkedServiceData linkedServiceData = new DataFactoryLinkedServiceData(azureBlobStorage);
var linkedServiceOperation = dataFactoryResource.GetDataFactoryLinkedServices().CreateOrUpdate(WaitUntil.Completed, storageLinkedServiceName, linkedServiceData);
Console.WriteLine(linkedServiceOperation.WaitForCompletionResponse().Content);
Vytvoření datové sady
Do metody Main přidejte následující kód, který vytvoří textovou datovou sadu s oddělovači.
Nadefinujete datovou sadu, která představuje data ke kopírování ze zdroje do jímky. V tomto příkladu odkazuje tato textová datová sada s oddělovači na propojenou službu Azure Blob Storage, kterou jste vytvořili v předchozím kroku. Datová sada má dva parametry, jejichž hodnota je nastavená v aktivitě, která datovou sadu využívá. Parametry se používají k vytvoření kontejneru a "folderPath" odkazující na umístění, kde se data nacházejí nebo jsou uložena.
// Create an Azure Blob dataset
DataFactoryLinkedServiceReference linkedServiceReference = new DataFactoryLinkedServiceReference(DataFactoryLinkedServiceReferenceType.LinkedServiceReference, storageLinkedServiceName);
DelimitedTextDataset delimitedTextDataset = new DelimitedTextDataset(linkedServiceReference)
{
DataLocation = new AzureBlobStorageLocation
{
Container = DataFactoryElement<string>.FromExpression("@dataset().container"),
FileName = DataFactoryElement<string>.FromExpression("@dataset().path")
},
Parameters =
{
new KeyValuePair<string, EntityParameterSpecification>("container",new EntityParameterSpecification(EntityParameterType.String)),
new KeyValuePair<string, EntityParameterSpecification>("path",new EntityParameterSpecification(EntityParameterType.String))
},
FirstRowAsHeader = false,
QuoteChar = "\"",
EscapeChar = "\\",
ColumnDelimiter = ","
};
DataFactoryDatasetData datasetData = new DataFactoryDatasetData(delimitedTextDataset);
var datasetOperation = dataFactoryResource.GetDataFactoryDatasets().CreateOrUpdate(WaitUntil.Completed, blobDatasetName, datasetData);
Console.WriteLine(datasetOperation.WaitForCompletionResponse().Content);
Vytvořit kanál
Do metody Main přidejte následující kód, který vytvoří kanál s aktivitou kopírování.
V tomto příkladu tento kanál obsahuje jednu aktivitu a přijímá čtyři parametry: vstupní kontejner objektů blob a cestu a výstupní kontejner objektů blob a cestu. Hodnoty pro tyto parametry se nastaví při aktivaci nebo spuštění kanálu. Aktivita kopírování odkazuje na stejnou datovou sadu objektů blob, kterou jste vytvořili v předchozím kroku jako vstup a výstup. Pokud se datová sada používá jako vstupní datová sada, zadává se vstupní kontejner a cesta. A když se datová sada použije jako výstupní datová sada, zadá se výstupní kontejner a cesta.
// Create a pipeline with a copy activity
Console.WriteLine("Creating pipeline " + pipelineName + "...");
DataFactoryPipelineData pipelineData = new DataFactoryPipelineData()
{
Parameters =
{
new KeyValuePair<string, EntityParameterSpecification>("inputContainer",new EntityParameterSpecification(EntityParameterType.String)),
new KeyValuePair<string, EntityParameterSpecification>("inputPath",new EntityParameterSpecification(EntityParameterType.String)),
new KeyValuePair<string, EntityParameterSpecification>("outputContainer",new EntityParameterSpecification(EntityParameterType.String)),
new KeyValuePair<string, EntityParameterSpecification>("outputPath",new EntityParameterSpecification(EntityParameterType.String))
},
Activities =
{
new CopyActivity("CopyFromBlobToBlob",new DataFactoryBlobSource(),new DataFactoryBlobSink())
{
Inputs =
{
new DatasetReference(DatasetReferenceType.DatasetReference,blobDatasetName)
{
Parameters =
{
new KeyValuePair<string, BinaryData>("container", BinaryData.FromString("\"@pipeline().parameters.inputContainer\"")),
new KeyValuePair<string, BinaryData>("path", BinaryData.FromString("\"@pipeline().parameters.inputPath\""))
}
}
},
Outputs =
{
new DatasetReference(DatasetReferenceType.DatasetReference,blobDatasetName)
{
Parameters =
{
new KeyValuePair<string, BinaryData>("container", BinaryData.FromString("\"@pipeline().parameters.outputContainer\"")),
new KeyValuePair<string, BinaryData>("path", BinaryData.FromString("\"@pipeline().parameters.outputPath\""))
}
}
}
}
}
};
var pipelineOperation = dataFactoryResource.GetDataFactoryPipelines().CreateOrUpdate(WaitUntil.Completed, pipelineName, pipelineData);
Console.WriteLine(pipelineOperation.WaitForCompletionResponse().Content);
Vytvoření spuštění kanálu
Do metody Main přidejte následující kód, který aktivuje spuštění kanálu.
Tento kód také nastavuje hodnoty inputContainer, inputPath, outputContainer a outputPath parametrů zadaných v kanálu se skutečnými hodnotami cest objektů blob zdroje a jímky.
// Create a pipeline run
Console.WriteLine("Creating pipeline run...");
Dictionary<string, BinaryData> parameters = new Dictionary<string, BinaryData>()
{
{ "inputContainer",BinaryData.FromObjectAsJson(inputBlobContainer) },
{ "inputPath",BinaryData.FromObjectAsJson(inputBlobPath) },
{ "outputContainer",BinaryData.FromObjectAsJson(outputBlobContainer) },
{ "outputPath",BinaryData.FromObjectAsJson(outputBlobPath) }
};
var pipelineResource = dataFactoryResource.GetDataFactoryPipeline(pipelineName);
var runResponse = pipelineResource.Value.CreateRun(parameters);
Console.WriteLine("Pipeline run ID: " + runResponse.Value.RunId);
Monitorování spuštění kanálu
Do metody Main přidejte následující kód, který nepřetržitě kontroluje stav, dokud se kopírování dat nedokončí.
// Monitor the pipeline run Console.WriteLine("Checking pipeline run status..."); DataFactoryPipelineRunInfo pipelineRun; while (true) { pipelineRun = dataFactoryResource.GetPipelineRun(runResponse.Value.RunId.ToString()); Console.WriteLine("Status: " + pipelineRun.Status); if (pipelineRun.Status == "InProgress" || pipelineRun.Status == "Queued") System.Threading.Thread.Sleep(15000); else break; }
Do metody Main přidejte následující kód, který načte podrobnosti o spuštění aktivity kopírování, například velikost načtených nebo zapsaných dat.
// Check the copy activity run details Console.WriteLine("Checking copy activity run details..."); var queryResponse = dataFactoryResource.GetActivityRun(pipelineRun.RunId.ToString(), new RunFilterContent(DateTime.UtcNow.AddMinutes(-10), DateTime.UtcNow.AddMinutes(10))); var enumerator = queryResponse.GetEnumerator(); enumerator.MoveNext(); if (pipelineRun.Status == "Succeeded") Console.WriteLine(enumerator.Current.Output); else Console.WriteLine(enumerator.Current.Error); Console.WriteLine("\nPress any key to exit..."); Console.ReadKey();
Spuštění kódu
Sestavte a spusťte aplikaci a potom ověřte spuštění kanálu.
Konzola vytiskne průběh vytváření datové továrny, propojených služeb, datových sad, kanálu a spuštění kanálu. Potom zkontroluje stav spuštění kanálu. Počkejte, až se zobrazí podrobnosti o spuštění aktivity kopírování s velikostí dat pro čtení a zápis. Pak pomocí nástrojů, jako je Průzkumník služby Azure Storage, zkontrolujte, že se objekty blob zkopírují do "outputBlobPath" z "inputBlobPath", jak jste zadali v proměnných.
Ukázkový výstup
Create a data factory quickstart-adf...
{
"name": "quickstart-adf",
"type": "Microsoft.DataFactory/factories",
"properties": {
"provisioningState": "Succeeded",
"version": "2018-06-01"
},
"location": "eastus2"
}
Create a linked service AzureBlobStorage...
{
"name": "AzureBlobStorage",
"type": "Microsoft.DataFactory/factories/linkedservices",
"properties": {
"type": "AzureBlobStorage",
"typeProperties": {
"connectionString": "DefaultEndpointsProtocol=https;AccountName=<storageAccountName>;",
"encryptedCredential": "<encryptedCredential>"
}
}
}
Creating dataset BlobDelimitedDataset...
{
"name": "BlobDelimitedDataset",
"type": "Microsoft.DataFactory/factories/datasets",
"properties": {
"type": "DelimitedText",
"linkedServiceName": {
"type": "LinkedServiceReference",
"referenceName": "AzureBlobStorage"
},
"parameters": {
"container": {
"type": "String"
},
"path": {
"type": "String"
}
},
"typeProperties": {
"location": {
"container": {
"type": "Expression",
"value": "@dataset().container"
},
"type": "AzureBlobStorageLocation",
"fileName": {
"type": "Expression",
"value": "@dataset().path"
}
},
"columnDelimiter": ",",
"quoteChar": "\"",
"escapeChar": "\\",
"firstRowAsHeader": false
}
}
}
Creating pipeline Adfv2QuickStartPipeline...
{
"properties": {
"activities": [
{
"inputs": [
{
"type": "DatasetReference",
"referenceName": "BlobDelimitedDataset",
"parameters": {
"container": "@pipeline().parameters.inputContainer",
"path": "@pipeline().parameters.inputPath"
}
}
],
"outputs": [
{
"type": "DatasetReference",
"referenceName": "BlobDelimitedDataset",
"parameters": {
"container": "@pipeline().parameters.outputContainer",
"path": "@pipeline().parameters.outputPath"
}
}
],
"name": "CopyFromBlobToBlob",
"type": "Copy",
"typeProperties": {
"source": {
"type": "BlobSource"
},
"sink": {
"type": "BlobSink"
}
}
}
],
"parameters": {
"inputContainer": {
"type": "String"
},
"inputPath": {
"type": "String"
},
"outputContainer": {
"type": "String"
},
"outputPath": {
"type": "String"
}
}
}
}
Creating pipeline run...
Pipeline run ID: 3aa26ffc-5bee-4db9-8bac-ccbc2d7b51c1
Checking pipeline run status...
Status: InProgress
Status: Succeeded
Checking copy activity run details...
{
"dataRead": 1048,
"dataWritten": 1048,
"filesRead": 1,
"filesWritten": 1,
"sourcePeakConnections": 1,
"sinkPeakConnections": 1,
"copyDuration": 8,
"throughput": 1.048,
"errors": [],
"effectiveIntegrationRuntime": "AutoResolveIntegrationRuntime (East US 2)",
"usedDataIntegrationUnits": 4,
"billingReference": {
"activityType": "DataMovement",
"billableDuration": [
{
"meterType": "AzureIR",
"duration": 0.06666666666666667,
"unit": "DIUHours"
}
],
"totalBillableDuration": [
{
"meterType": "AzureIR",
"duration": 0.06666666666666667,
"unit": "DIUHours"
}
]
},
"usedParallelCopies": 1,
"executionDetails": [
{
"source": {
"type": "AzureBlobStorage"
},
"sink": {
"type": "AzureBlobStorage"
},
"status": "Succeeded",
"start": "2023-12-15T10:25:33.9991558Z",
"duration": 8,
"usedDataIntegrationUnits": 4,
"usedParallelCopies": 1,
"profile": {
"queue": {
"status": "Completed",
"duration": 5
},
"transfer": {
"status": "Completed",
"duration": 1,
"details": {
"listingSource": {
"type": "AzureBlobStorage",
"workingDuration": 0
},
"readingFromSource": {
"type": "AzureBlobStorage",
"workingDuration": 0
},
"writingToSink": {
"type": "AzureBlobStorage",
"workingDuration": 0
}
}
}
},
"detailedDurations": {
"queuingDuration": 5,
"transferDuration": 1
}
}
],
"dataConsistencyVerification": {
"VerificationResult": "NotVerified"
}
}
Press any key to exit...
Ověření výstupu
Kanál automaticky vytvoří výstupní složku v kontejneru objektů blob adftutorial . Potom zkopíruje soubor emp.txt ze vstupní složky do výstupní složky.
- Na webu Azure Portal na stránce kontejneru adftutorial , na které jste se zastavili v části Přidat vstupní složku a soubor kontejneru objektů blob výše, vyberte Aktualizovat a zobrazte výstupní složku.
- V seznamu složek vyberte výstup.
- Potvrďte, že je do výstupní složky zkopírovaný soubor emp.txt.
Vyčištění prostředků
Pokud chcete objekt pro vytváření dat odstranit programově, přidejte do programu následující řádky kódu:
Console.WriteLine("Deleting the data factory");
dataFactoryResource.Delete(WaitUntil.Completed);
Další kroky
Kanál v této ukázce kopíruje data z jednoho umístění do jiného umístění v úložišti objektů blob Azure. Projděte si kurzy, kde se dozvíte o použití služby Data Factory ve více scénářích.