














1. .netTiers Introduction Top
CodeSmith is a template driven code generator that can be used with VB or C# and can generate any language or text you wish. As developers, several aspects of of our craft have come full circle, where code generation has matured to a point where it has become a necessity and preferred practice. Code generation helps protect against the mistakes of man. Once you've solidified your code generation process, the chance of bugs entering a bug in a certain peice of code drop dramatically. And should a bug appear, you simply have to change your templates and it will correct itself accross the entire application. Much better than the previous way of relying on yourself to find all instances of a scenario where the behavior caused by the bug was failing. Not to take anything away from the extremely powerful refactoring tools today, they help us out tremendously, but they are very limited when it comes down to actually changing behavior, where code generation is much better suited. A CodeSmith template allows you to define properties that can be used along with rich meta-data to create the most powerful of templates, and the best part, it looks and acts just like Asp.net. Your options for a rich meta data include, RDBMS, XML, .net Types, or easily create your own.
.netTiers is a library of open source CodeSmith templates written in C#. The intention of the templates are to assist developers with the intention of eliminating repetative mundane coding, and at the same time, provide a full fledged framework that allows you to get started working on what matters the most to you in your applications. For example, focusing your efforts with the presentation layer, business rules, workflow, and application health for your application to become a success. Consider .netTiers an application block, only specialized to your domain model, and the growth from within the product will more likely be vertically more than horizontally. Meaning, future versions will be focusing on providing more things out of the box which will assist you in your everyday development tasks.
The templates effectively build a set of object-relational domain objects for an existing database based off of Model Driven Design (MDD). MDD essentially is the concept where a predesigned model is used to generate your application. MDD was made famouis by many UML modelers, such as Rational Rose, etc. However, with the advent of CodeSmith's rich set meta-data via it's SchemaExplorer, MDD has been particularly easy to adopt for .netTiers through the familiar data model. It's .netTiers responsibility to have the ability to take a good database design and yield a wonderful generated domain for your codebase. Since the majority of business applications revolve around data, .netTiers offers up the ability to work with your data in the easiest way possible as soon as possible.
This is a generalized list of features that .netTiers provides. You can find more information on these topics within the documentation.
.netTiers are a set of templates written in C# and is built to work with the CodeSmith template code generation platform. CodeSmith itself uses a familiar Asp.net syntax so .netTiers is not written in any obscure language or syntax that you couldn't sit down and understand what's going on in a very short time. The power of .netTiers is that it's a templatized approach to a common problem, and does not prohibit you from changing things or knowing what's going on under the covers.
2. Installing .netTiers Top
Once you have downloaded the .netTiers .zip file from the www.netTiers.com/download website, simply extract the files to your favorite projects directory. It's required that you have CodeSmith installed and registered by this point on your system. Here's a glimpse into what you'll see when you extract the directories. We'll delve more into the folder hierarchy later, but right now we're simply interested in doing our first generation.

3. Required Setup Top
To execute, you simply have to run (double-click) the main template, NetTiers.cst found in the root of the folder found where you extracted the templates.
At the bare minimum, you must fill out the first 3 properties as seen in the image to the left.
Choose Source Database:
This property is the heart of the .netTiers meta data for generation. You should select the database that the tables views, and stored procedures should be based on for generation. IMPORTANT!!! If SourceTables and SourceViews are left blank, the Entire Database will then be generated.
If you don't see your datasource, you will have to create one of your own, click Add.
Now that you've created your own entry, you can select it for generation. Setting this property will also try to default the the values of the OutputDirectory and your RootNameSpace by appending the datasource name to them. Depicted to the in the image above, Northwind was selected as our datasource, and the output directory appended became "C:\NetTiers\Northwind" and Northwind also became the root namespace.
OutputDirectory: The root windows directory to output the generated project to. It's usually best that this be a new directory unless you've worked with the templates for awhile.
RootNameSpace: Root namespace for generated projects and C# classes. This will be the prefix for the other project namespaces. Example: If you enter NetTiers.Northwind here, and you enter Entities in BLLNamespace, then you will see NetTiers.Northwind.Entities for your Entity Layer.
Note: This is all that is required to generate a successful Data Access Layer from the .netTiers templates. There are many more options and other layers you can generate, you can skip down to #4, Configuration if you don't want to see the added generation options.
4. Advanced Setup Top

EnumTables: The tables to generate as enums. Your columns must meet the following rules. The first column must be a primary key and an Identity column, the second column must have a unique column constraint index, the optional third column will be the description of the generated enum. You must also select this table in the SourceTable as well in order to generate the enum.
SourceTables: The tables you wish to generate into entities, if you do not select any SourceTables or SourceViews, and SourceDatabase is completed, then the entire database will be generated.
SourceViews: The views you wish to generate into entities, if you do not select any SourceTables or SourceViews, and SourceDatabase is completed, then the entire database will be generated.
CustomCodeFolderName: If specified, indicates the name of a folder that can contains custom classes to dynamically add to each project. This is useful if you plan on adding customized code aside from using the concrete classes or helper methods to any of the generated projects.
ExecuteSql: If true the stored procedures are attempted to be installed on the sql server for you. (The SQL file is still generated and placed in the Namespace.SQL directory).
IncludeComponentLayer: The pattern type to implement in the Component Layer. The component layer is considered to be where you core business rule implementations and in new implementations should be the entry point into your domain logic. You can choose either Service Layer (like the Manager pattern), or Domain Model.
NOTE: The ServiceLayer is by far the most flexible and offers advanced features throughout the framework, like a workflow pipeline and a workspace. The DomainModel should be used on basic applications and prototypes not requiring advanced workflow and loose coupling logic.
IncludeDatabaseFeatures: Indicates which database specific features to generate. The default is SQL 2000 compatibility, but you can select optionally choose Sql2005, which will generate optimized paging procedures specifically for SQL Server 2005.
IncludeUnitTest: Indicates type of Unit tests to be generated. The options are:
BusinessLogicLayerNameSpace: The sub-namespace that is added to the root namespace for the Entity Layer. So if RootNameSpace = "Northwind", and this property is "Entities" the resultant namespace for the entities would Northwind.Entities
ComponentLayerNameSpace: The sub-namespace for the given business layer you choose in the IncludeComponentLayer property. So if RootNameSpace = "Northwind", and this property is "Services" the resultant namespace for the services would Northwind.Services
DataAccessLayerNameSpace: The sub-namespace that is added to the root namespace for the Base Data Access Layer. So if RootNameSpace = "Northwind", and this property is "Data" the resultant namespace for the base data access layer would Northwind.Data
UnitTestsNameSpace: The sub-namespace that is added to the root namespace for the UnitTest Layer. So if RootNameSpace = "Northwind", the resultant namespace for the unit test swould Northwind.UnitTests
CompanyName: The name of your company, or client's company. This is only for documenation and any references to the company.
CompanyURL: The URL of your company, or client's company. This is only for documenation and any references to the company.
SignAssembly: If true, the generated projects, when building, will try to sign the assemblies and search for the snk in the local root directory(OutputDirectory). This strong names your assemblies and is useful for advanced .net options and security.
GenerateWebLibrary: Indicates if the web library should be generated. This contains the EntityDataSource, Specialized Typed DataSource controls of your domain and other extremely helpful Asp.Net utility classes.
IncludeDesignTimeSupport: Indicates if Visual Studio design-time support should be provided for the Web Library Typed DataSource controls.
GenerateWebAdmin: Indicates if the web admin user controls should be generated. These are CRUD control admin screens that you can use to help manage
GenerateWebService: Indicates if the Webservice DataAccess Provider should be generated. If you are in a situation where you need to create an EndPoint of your Data API, then include this option.
WebAdminOutputPath: The full path for generated WebAdmin UserControl files.
WebServiceOutputPath: The full path for the the WebService files. This path must match with the WebserviceURL in IIS.
WebServiceURL: The base URL for the webservice specified above in WebServiceOutputPath, eg: http://localhost/NetTiersWS.
GenerateWebsite: Indicates if a complete website should be generated. This is useful for new webform projects and you need to get up and going immediately. A full website along with all necessary references will already be included and ready to start working with your data.
IncludeAtlasLibrary: Indicates whether to include a reference to the Microsoft Atlas Component Library in the website generated. This is useful if you want to immediately take advantage of the Microsoft Atlas Framework in your WebForms.
IncludeAtlasToolkit: Indicates whether to include a reference to the Atlas Control Toolkit. This property is only taken into account when IncludeAtlasLibrary is true. The Microsoft Atlas Toolkit is a set of advanced controls that take full advantage of ajax and javascript behaviors.
OverwriteWebConfig: Indicates if the Web.config should be overwritten in the GenerateWebsite generated website project. This is useful if you've customized your web.config and don't want to overwrite those settings.
UseWebAppProject: Indicates if a Web Application Project file should be generated. Note: you must have the Visual Studio Maintenance Patch and the WebApplication Projects Visual Studio Extension installed in order to use this feature. This creates a project file for website project much like Visual Studio 2003.
CustomNonMatchingReturnType: When using custom stored procedures, if the returned rows do not match the fields in an entity, a DataSet or IDataReader will be returned. Choose One. This is useful if you've returned more than one resultset in a custom procedure; you can use a ConvertToDataSet(IDataReader) method in the Utility class to convert that to a DataSet.
CustomProcedureStartsWith: include custom stored procedures, this is the pattern that NetTiers will look for your custom stored procedures to start with. A string format will be used to match the beginning of the procedure pattern. So, {0}=TableName, {1}=ProcedurePrefix(See Property Below). By default NetTiers will look at tables that starts with '_{0}_', which means it will detect the procedure _TableName_GetByBirthdate and generate the necessary plumbing to wrap your custom stored procedure. Your new method can be accessed by DataRepository.TableNameProvider.GetByBirthdate();
IncludeCustoms: Indicates if you would like .netTiers to attempt to generate wrappers into the API for your custom stored procedures.
IncludeDelete: If true delete procedures will be generated into the API.
IncludeDrop: If true drop comands along with all of the stored procedures will be generated.
IncludeFind: If true Find procedures will be generated into the API.
IncludeGet: If true Get procedures will be generated into the API.
IncludeGetList: If true GetList procedures will be generated into the API.
IncludeGetListByFK: If true GetList By Foreign Key procedures will be generated into the API. So if your Order Table has a CustomerId column in it, and its a foreign key back to your Customers Table. Then a method called GetByCustomerId(int customerId) will be created.
IncludeGetListByIX: If true GetList By Index procedures will be generated into the API. So if your Order Table has a Status column in it, and its an index onf your Orders Table. Then a method called GetByStatus(string status) will be created.
IncludeInsert: If true Insert procedures will be generated into the API.
IncludeManyToMany: If true .netTiers will attempt to gain insight into your many to many relationships and generate procedures into the API.
IncludeRelations: If true .netTiers will use the your database meta data to discover relationships and will generate into the API.
IncludeSave: If true save methods will be generated into the API that wrap Insert/Update/Delete.
IncludeUpdate: If true update procedures will be generated into the API.
IsolationLevel: Isolation level to use for the generated procedures.
RetryEnabled: Enabling Retry will add code retry the queries that failed with data exceptions. Useful to if your database becomes temporarily unavailable. Use with caution in that if a transaction fails in the database, then the retry can not continue because the transaction is now in a failed state.
RetryMaxAttempts: The number of attempts that will be made.
RetrySleepStyle:
DeleteSuffix: Suffix to use for all generated DELETE stored procedures.
FindSuffix: Suffix to use for all generated selective FIND stored procedures.
GrantUser: Optional user or role to GRANT EXEC Procedure permissions to
ProcedurePrefix: The prefix to attach to the stored procedure names, ex: "usp_" will give you "usp_Orders_GetList"
SelectAllSuffix: Suffix to use for all generated selective SELECT stored procedures.
UpdateSuffix: Suffix to use for all generated selective Update stored procedures.
AliasFilePath: Optional File Path to a table/object alias file. If you have a table name called "Customers" and you wanted it to be "Customer" then you would create a "Customer" table. Create a NewLine Delimited list of the table names and their Aliases, seperated by a column. This is also useful if you encounter a naming collision with a type that's already included in the .Net Framework. For example if you have a table named Environment, then you will get a naming conflict with the .Net Type Environment.
Alias.txt
------------------------------
Customers:Customer Orders:OrderBaseClassFormat: The format for any base class name. Parameter {0} is replaced by the original class name.
5. .netTiers Generation Top

Save Property Set: The first thing you want to do is save your property set, which is noted by the Arrow and turquoise highlight. This enables you to quickly reload your property without having to re-configure your property set.
Expand Window: Second, click the arrows depicted by the green area to expand the window so you can see the Template Output. This will let you see any error messages, if any.
Generate: Third, click the generate button and wait approximately 30 seconds to 2 minutes depending on this size of the database. Depending on whether or not you chose to view the Generation Report, once .netTiers is completed, your default browser will pop-up showing the generation report.
Summary: The summary section of the report gives you an overall synopsis of total objects or errors that occured during the generation process.
Configuration: The .netTiers Quick Configuration is a section that enables you to quickly configure your winforms or web application. Essentially it requires you to add a section to your configuration section to your web/app config of the NetTiersServiceSection. This allows .netTiers to read critical information during runtime.
Documentation: The documentation section has a link back to the official .netTiers documentation. Which will most likely be this file. It also contains a very useful quick start of sample API calls, which is meant to get you used to how you make calls into your customized API.
Details - Generated Classes: This is a "rather long" list of all your generated objects. This is useful if you added a new table to your generation process, but you don't see the objects for them, you can check here and verify if the table actually got created.
Browse to OutputDirectory: Using Windows Explorer, browse to the OutputDirectory that you chose earlier in the setup process. You will see a solution file, along with several directories. Each directory represents usually Tier in generated code. Let's make sure your generation process was completely successful before you import this into an existing solution if you already have one.
Open Solution: Double click this solution file. You can later attach any new project to this solution. However, even if you're starting from scratch we recommend making a new solution, that is yours and simply importing this solution into your solution. This will allow you to change things up as much as you want in a flexible manner and still not have to worrry about ruining anything. Things like SCC can potentially change the way you work with the templates, so careful seperation will allow you to be happy with the results. This new solution can be a Master Solution of sorts that can contains a web/winforms app, and includes the NetTiers projects. You would also have our Generated solution, which is nice and lean for your quick entity and data layer modifications.
6. .netTiers Configuration Top

<section name="Northwind.Data" type="Northwind.Data.Bases.NetTiersServiceSection, Northwind.Data" allowDefinition="MachineToApplication" restartOnExternalChanges="true" />
Remember, the Connection String name corresponds to the Asp.Net ConnectionString config section you are using. The Northwind.Data Section of the configuration is the critical data that .netTiers needs to know in order to run successfully at runtime.
7. Ready to Code Top



Taking the form and selecting only the columns that I want, we create a nice grid.
When you want to actually interact with the data, you simply have to include your the generated tiers as using directives. We recommend as much encapsulation as possible, with both your Service Objects and your Collection/Entity classes.
AccountService accountsService = new AccountsService();//GetAll()
TList<Accounts> accountList = accountsService.GetAll();
//GetPagedl()
TList<Accounts> accountList =
accountsService.GetPaged("IsActive = 1 AND AccountName LIKE 'smi%'");
//GetByFk()
TList<Accounts> accountList = accountsService.GetByCustomerId(25);
//GetIX()
TList<Accounts> accountList = accountsService.GetByAccountCreatedDate(new DateTime("1/1/2006"));//Get()
entity.Entitykey;
TList<Accounts> accountList = accountsService.Get(entity.EntityKey);
Account accountEntity = new Account();
accountEntity.AccountName = "MyAccountName";
accountEntity.CreatedDate = DateTime.Now;
//Insert()
TList<Accounts> accountList = accountsService.Insert(accountEntity);//Delete()
TList<Accounts> accountList = accountsService.Delete(accountEntity);
//Delete()
TList<Accounts> accountList = accountsService.Delete(23);
//Update()
accountEntity.AccountName = "MyAccountName 2";
TList<Accounts> accountList = accountsService.Update(accountEntity);
//GetByManyToManyl()
TList<Customers> accountList = accountsService.GetCustomers_From_AccountsReceivable();
//GetCustomProcedureName()
TList<Accounts> accountList = accountsService.GetByAccountMaturationDate();
//DeepLoadByIdl() using PK
Account account = accountsService.DeepLoadByAccountId(id, false, DeepLoadType.IncludeChildren, typeof(Customers), typeof(TList<ChartOfAccounts>));//DeepLoadByIdl() using FK
TList<Account> account = accountsService.DeepLoadByCustomerId(id, false, DeepLoadType.IncludeChildren, typeof(Customers), typeof(TList<ChartOfAccounts>));//already instatiated objects
//DeepLoad
TList<Account> account = accountsService.DeepLoad(myAccountEntity, false, DeepLoadType.IncludeChildren, typeof(Customers), typeof(TList<ChartOfAccounts>));//DeepSave
TList<Account> account = accountsService.DeepSave(myAccountEntity, false, DeepSaveType.IncludeChildren, typeof(Customers), typeof(TList<ChartOfAccounts>));
You will quickly discover that while there is a slew code being generated, the concepts themselves are simple, and familiar concepts based on proven practices and patterns.
string custId = "TRAIH";
//I get a single instance of the customer I want.
Customers customer = DataRepository.CustomersProvider.GetByCustomerID(custId);
Type [] typesToDeepLoad = new Type[] { typeof(TList<Orders>), typeof(TList<Products>) };
//go further than one level down object graph
bool goMoreThanOneLevelDeep = true;
// I'm going to deep load this customer, but I only want
// to see his orders and the products that he's made,
// I really don't care about the line items
// But the neat thing is that the relationship to products is through // line items.
/// the object graph looks somethign like this
/// - Customer
/// --Order
/// ---OrderDetails
/// ---ProductCollection
/// --CustomerDemographics
/// --CustomerDemographicsCollection_From_CustomerCustomerDemo
/// (a strangely named northwind thing, but shows how many to many relationships work.)
DataRepository.CustomersProvider.DeepLoad(
customer, // my customer
goMoreThanOneLevelDeep, //go further than one level down object graph
DeepLoadType.IncludeChildren, //be Inclusive, instead of exclusive
typesToDeepLoad );
8. Architecture Top
This data tiers concept is composed of custom business entities components (the data itself) and data access logic components (the persistence logic).
This design is inspired from the Microsoft patterns & practices guide:
Designing Data Tier Components and Passing Data Through Tiers:
Here's general information on the patterns used in .netTiers 2.
Information mostly aggregated from these wonderful developer resources:
patternshare.org | dofactory.com | DavidHayden.com
ServiceLayer
http://patternshare.org/default.aspx/Home.MF.ServiceLayer
Processors
By default is a Pipeline:
http://patternshare.org/default.aspx/Home.HW.PipesAndFilters
but easily can be used with workflow management in:
http://patternshare.org/default.aspx/Home.HW.ProcessManager
Each Processor -
Command
http://www.dofactory.com/Patterns/PatternCommand.aspx
Flexible enough to be used within a strategy passed into the ctor to manage different behaviors in complex logic.
http://www.dofactory.com/Patterns/PatternStrategy.aspx
DomainModel + ActiveRecord
http://patternshare.org/default.aspx/Home.MF.DomainModel
http://patternshare.org/default.aspx/Home.MF.ActiveRecord
Data Access Layer
DataRepository.cs - Singleton, Decorator
http://patternshare.org/default.aspx/Home.PP.Singleton
http://www.dofactory.com/Patterns/PatternDecorator.aspx
Uses the entities as Data Transfer Objects:
http://patternshare.org/default.aspx/Home.MF.DataTransferObject
Repository Provider:
http://davidhayden.com/blog/dave/archive/2004/05/19/259.aspx
Entity Layer - Factory, Memento, State
Entity - Memento, State, DomainModel, TableModule
http://www.dofactory.com/Patterns/PatternMemento.aspx
http://www.dofactory.com/Patterns/PatternState.aspx#_self2
http://patternshare.org/default.aspx/Home.MF.DomainModel
http://patternshare.org/default.aspx/Home.MF.TableModule
Entity Factory
http://www.dofactory.com/Patterns/PatternFactory.aspx
WebService Client - Proxy
http://www.dofactory.com/Patterns/PatternProxy.aspx
New Sql Expression Code - Builder
http://www.dofactory.com/Patterns/PatternBuilder.aspx
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。