多层架构应用介绍

Xenta是一个开源项目,可免费使用,采用.NET/C#编程语言开发,最初针对基于Web的解决方案。它采用修改后的MIT许可证。本文旨在介绍Xenta的架构。要使用源代码,需要Microsoft Visual Studio 2010。

架构概览

Xenta具有4层结构:

  • 数据访问层(DAL)
  • 业务逻辑层(BLL)
  • 服务层
  • 表示层

每一层都包含自己的实体,实体在通过层时进行映射(例如,DAL实体映射到BLL实体)。

数据访问层(DAL)

数据访问层由数据抽象和每个具体数据源的抽象实现组成。数据抽象描述数据实体和数据提供程序接口。数据实体的基类是DataEntityBase。对于数据提供程序接口,有基接口IDataProvider。提供程序实例化基于配置文件。默认数据源是Microsoft SQL Server(2005或更高版本),但相信,更改数据源非常简单。

public interface IDataProvider { void Initialize(string name, NameValueCollection properties); } public interface IUserDataProvider : IDataProvider { bool InsertUser(Guid guid, string username, string firstName, string lastName, Gender gender, DateTime? birthDate, string email, string comment, string passwordHash, string passwordSalt, int languageID, int currencyID, int timeZoneID, int countryID, bool isActive, DateTime createdOn, DateTime updatedOn, out int userID); UserData GetUser(int userID); UserData GetUserByEmail(string email); UserData GetUserByUsername(string username); UserData GetUserByGuid(Guid guid); UserDataCollection GetAllUsers(string searchTerm, int? roleID, int? countryID, int? languageID, int? currencyID, int? timeZoneID, DateTime? createdOnStart, DateTime? createdOnEnd, bool showHidden, int startIndex, int count, out int totalCount); bool UpdateUser(int userID, Guid guid, string username, string firstName, string lastName, Gender gender, DateTime? birthDate, string email, string comment, string passwordHash, string passwordSalt, int languageID, int currencyID, int timeZoneID, int countryID, bool isActive, DateTime createdOn, DateTime updatedOn); bool DeleteUser(int userID); } <xentaDAL> <providers> <add name="UserDataProvider" type="SiberTek.Xenta.Data.Providers.UserDataProvider, SiberTek.Xenta.Data.MsSqlServer.Core" connection="MsSqlServerConnection" /> </providers> </xentaDAL>

业务逻辑层(BLL)

BLL描述业务规则和管理逻辑。它包含业务实体、管理器、任务等。实体继承自BusinessEntityBase。每个管理器实现IManager接口。通常管理器是单例。管理器可以包含事件,这些事件可以由其他管理器或任务或其他东西处理。例如,定义了EntityEventArgs类和EntityEventHandler委托,用于与实体操作相关的事件,如创建/更新/删除。

public class UserManager : IManager { private const string GuestUsername = "guest"; private static UserManager _instance = null; private bool _initialized; private IUserDataProvider _userDataProvider; private IUserAttributeDataProvider _attributeDataProvider; private IUserSessionDataProvider _sessionDataProvider; private UserManager() { _initialized = false; _userDataProvider = null; _attributeDataProvider = null; _sessionDataProvider = null; } public event EntityEventHandler UserCreated; public event EntityEventHandler UserUpdated; public event EntityEventHandler UserDeleted; public static UserManager Instance { get { if (_instance == null) { _instance = new UserManager(); } return _instance; } } } public interface ITask { TimeSpan Period { get; } void Initialize(NameValueCollection properties); void TaskProc(); } <tasks> <add name="MessageDispatcher" type="SiberTek.Xenta.Tasks.MessageDispatcher, SiberTek.Xenta.Core" /> </tasks>

服务层

这一层基于WCF技术。它允许在不同的物理服务器上部署Xenta层,在一台服务器上或甚至在一个应用程序中。服务托管在Xenta.Services.Host应用程序中。

[ServiceContract] public interface ICoreService { [OperationContract] [FaultContract(typeof(XentaFault))] User CreateUser(string username, string firstName, string lastName, Gender gender, DateTime? birthDate, string email, string comment, string password, int languageID, int currencyID, int timeZoneID, int countryID); [OperationContract] User GetUser(int userID); [OperationContract] User GetGuestUser(); [OperationContract] User GetUserByUsername(string username); [OperationContract] User GetUserByEmail(string email); [OperationContract] User GetUserByGuid(Guid guid); [OperationContract] UserCollection GetAllUsers(string searchTerm, int? roleID, int? countryID, int? languageID, int? currencyID, int? timeZoneID, DateTime? createdOnStart, DateTime? createdOnEnd, bool showHidden, int startIndex, int count); [OperationContract] bool IsUsernameBusy(string username); [OperationContract] bool IsEmailBusy(string email); [OperationContract] bool IsUserPasswordValid(int userID, string password); [OperationContract] [FaultContract(typeof(XentaFault))] bool UpdateUserPassword(int userID, string password); [OperationContract] [FaultContract(typeof(XentaFault))] bool ActivateUser(int userID); [OperationContract] bool IsUserActive(int userID); }

表示层

  • 模型 - 可通过服务访问的业务逻辑
  • 视图 - Web应用程序
  • 呈现器 - 通过服务访问模型的呈现器和辅助类
public class UserPresenter : PresenterBase { public void Update() { ViewDataContainer item = View.DataContainer["User"] as ViewDataContainer; int userID = (int)item["UserID"]; string username = (string)item["Username"]; string email = (string)item["Email"]; string firstName = (string)item["FirstName"]; string lastName = (string)item["LastName"]; bool isActive = (bool)item["IsActive"]; Gender gender = (Gender)item["Gender"]; DateTime? birthDate = (DateTime?)item["BirthDate"]; string comment = (string)item["Comment"]; int languageID = (int)item["LanguageID"]; int countryID = (int)item["CountryID"]; int timeZoneID = (int)item["TimeZoneID"]; int currencyID = (int)item["CurrencyID"]; if (birthDate.HasValue) { birthDate = UserContext.Current.DateTimeConvertToUtc(birthDate.Value); } using (CoreServiceClient svc = new CoreServiceClient()) { svc.UpdateUser(userID, username, firstName, lastName, gender, birthDate, email, comment, languageID, currencyID, timeZoneID, countryID, isActive); } } } public partial class UserForm : ViewBase, IForm, ICommandHandler { [Browsable(false)] public int? UserID { get { return StringHelper.Parse(txtUserID.Text); } set { txtUserID.Text = value.HasValue ? value.ToString() : String.Empty; } } public string ValidationGroup { set { vldUsername.ValidationGroup = value; vldEmail.ValidationGroup = value; vldEmail2.ValidationGroup = value; vldPassword.ValidationGroup = value; vldPassword2.ValidationGroup = value; vldFileQuota.ValidationGroup = value; } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485