Web Service Software Factory

ソフトウエア・ファクトリの具体例として出てきているもので、Webサービス+データアクセスのコード生成が出来るようになっています。
以前、評価しようとしてインストールしていたのだが、仕組みのGAT(Guidance Automation Toolkit)の方が気になり、DEEPな世界に足を踏み入れ挫折していました。たまたま、少し動かしてみると、案外面白そうなのでメモがてら紹介しておきます。ウイザード画面と生成されるコードが一番イメージが伝わるかな。

データアクセス

テーブルを指定すると単純なCRUDのストプロのコードを生成してくれます。


ALTER PROCEDURE [dbo].[InsertCategories]
	@categoryID int OUT,
	@categoryName nvarchar(15),
	@description ntext = NULL,
	@picture image = NULL
AS
BEGIN
	SET NOCOUNT ON
	
	BEGIN TRY
	INSERT INTO [dbo].[Categories] ([CategoryName], [Description], [Picture])
	VALUES (@categoryName, @description, @picture)
	SET @categoryID = SCOPE_IDENTITY()
	END TRY

	BEGIN CATCH
		EXEC RethrowError;
	END CATCH
	
	SET NOCOUNT OFF
END
	

GO

IF NOT EXISTS (SELECT NAME FROM sys.objects WHERE TYPE = 'P' AND NAME = 'UpdateCategories')
BEGIN
	EXEC('CREATE PROCEDURE [dbo].[UpdateCategories] AS RETURN')
END

GO

ALTER PROCEDURE [dbo].[UpdateCategories]
	@categoryID int,
	@categoryName nvarchar(15),
	@description ntext = NULL,
	@picture image = NULL
AS
BEGIN

	--The [dbo].[Categories] table doesn't have a timestamp column. 
Optimistic concurrency logic cannot be generated
	SET NOCOUNT ON

	BEGIN TRY
	UPDATE [dbo].[Categories] 
	SET [CategoryName] = @categoryName, [Description] = @description, [Picture] = @picture
	WHERE [CategoryID]=@categoryID

	IF @@ROWCOUNT = 0
	BEGIN
		RAISERROR('Concurrent update error. Updated aborted.', 16, 2)
	END
	END TRY

	BEGIN CATCH
		EXEC RethrowError;
	END CATCH
		

	SET NOCOUNT OFF
END

GO

IF NOT EXISTS (SELECT NAME FROM sys.objects WHERE TYPE = 'P' AND NAME = 'DeleteCategories')
BEGIN
	EXEC('CREATE PROCEDURE [dbo].[DeleteCategories] AS RETURN')
END

GO

ALTER PROCEDURE [dbo].[DeleteCategories]
	@categoryID int
AS
BEGIN
	SET NOCOUNT ON
	
	DELETE FROM [dbo].[Categories]
	WHERE [CategoryID]=@categoryID
	
	SET NOCOUNT OFF
END

GO

IF NOT EXISTS (SELECT NAME FROM sys.objects WHERE TYPE = 'P' AND NAME = 'GetAllFromCategories')
BEGIN
	EXEC('CREATE PROCEDURE [dbo].[GetAllFromCategories] AS RETURN')
END

GO

ALTER PROCEDURE [dbo].[GetAllFromCategories]
	
AS
BEGIN
	SET NOCOUNT ON
	
	SELECT
	[categories].[CategoryID] AS 'CategoryID',
	[categories].[CategoryName] AS 'CategoryName',
	[categories].[Description] AS 'Description',
	[categories].[Picture] AS 'Picture'
FROM [dbo].[Categories] [categories]

	SET NOCOUNT OFF
END

GO

IF NOT EXISTS (SELECT NAME FROM sys.objects WHERE TYPE = 'P' AND NAME = 'GetCategoriesByCategoryID')
BEGIN
	EXEC('CREATE PROCEDURE [dbo].[GetCategoriesByCategoryID] AS RETURN')
END

GO

ALTER PROCEDURE [dbo].[GetCategoriesByCategoryID] 
	@categoryID int
AS
BEGIN

	SET NOCOUNT ON
	
	SELECT
	[categories].[CategoryID] AS 'CategoryID',
	[categories].[CategoryName] AS 'CategoryName',
	[categories].[Description] AS 'Description',
	[categories].[Picture] AS 'Picture'
	FROM [dbo].[Categories] [categories]
	WHERE [CategoryID]=@categoryID

	SET NOCOUNT OFF
END

GO

ビジネスエンティティの生成

テーブルを指定するとエンティティクラスを生成してくれます。型指定されたDataSetじゃ無く、POCO(素のクラス)を生成します。


public partial class Region
{
	public Region()
	{
	}

	public Region(System.String regionDescription, System.Int32 regionID)
	{
		this.regionDescriptionField = regionDescription;
		this.regionIDField = regionID;
	}

	private System.String regionDescriptionField;

	public System.String RegionDescription
	{
		get { return this.regionDescriptionField; }
		set { this.regionDescriptionField = value; }
	}

	private System.Int32 regionIDField;

	public System.Int32 RegionID
	{
		get { return this.regionIDField; }
		set { this.regionIDField = value; }
	}

}

サービススキーマの定義

Webサービスで受け渡すスキーマ構造を定義します。早い話がDTOみたいなものです。

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlRootAttribute(
Namespace = "http://ASMXService1.DataTypes/2006/11", IsNullable = false)]
public class Product
{

	private string productID;

	private string productName;

	public string ProductID
	{
		get
		{
			return this.productID;
		}
		set
		{
			this.productID = value;
		}
	}

	public string ProductName
	{
		get
		{
			return this.productName;
		}
		set
		{
			this.productName = value;
		}
	}
}

ビジネスエンティティとサービススキーマの変換処理

サービス指向にクラスを公開するのではなくスキーマを公開するという考え方があります。このため、外部向けのサービススキーマと内部のビジネスエンティティの2つのデータ構造が作成されます。この変換を行う処理を生成できるようにしているようです。


public class TranslateBetweenSampleDataAndCustomers
{

	public ASMXService1.BusinessEntities.Customers TranslateSampleDataToCustomers
(ASMXService1.DataTypes.SampleData from)
	{
		ASMXService1.BusinessEntities.Customers to 
= new ASMXService1.BusinessEntities.Customers();
		to.Address = from.Address;
		to.City = from.City;
		to.CompanyName = from.CompanyName;
		to.ContactName = from.ContactName;
		to.ContactTitle = from.ContactTitle;
		to.Country = from.Country;
		to.CustomerID = from.CustomerID;
		to.Fax = from.Fax;
		to.Phone = from.Phone;
		to.PostalCode = from.PostalCode;
		to.Region = from.Region;
		return to;
	}

	public ASMXService1.DataTypes.SampleData TranslateCustomersToSampleData
(ASMXService1.BusinessEntities.Customers from)
	{
		ASMXService1.DataTypes.SampleData to = new ASMXService1.DataTypes.SampleData();
		to.Address = from.Address;
		to.City = from.City;
		to.CompanyName = from.CompanyName;
		to.ContactName = from.ContactName;
		to.ContactTitle = from.ContactTitle;
		to.Country = from.Country;
		to.CustomerID = from.CustomerID;
		to.Fax = from.Fax;
		to.Phone = from.Phone;
		to.PostalCode = from.PostalCode;
		to.Region = from.Region;
		return to;
	}
}