上篇我们看了登陆界面,本篇我对服务端进行一个剖析。以及主界面的设计。我们上次忘记解释一个Silverlight的项目如何寄宿在MVC项目上。我们先来看看如何寄宿。看下图
我们看到了MISInfoManage这个项目是一个Silverlight项目。它寄宿在MISInfomanage.Web.Host这个MVC3项目中。流程是这样的,Silverlight寄宿在MISInfomanage.Web.Host上,MISInfomanage.Web.Host这个项目它的启动路径如下图所示,是Home/Index,完整路径就是Http://localhost:port/Home/Index。
我们来看看控制器代码
- using System;
@H_404_24@ using System.Collections.Generic;- using System.Linq;
@H_404_24@ using System.Web;- using System.Web.Mvc;
@H_404_24@- namespace MISInfoManage.Web.Controllers
@H_404_24@{- public class HomeController : Controller
@H_404_24@ {- //
@H_404_24@ // GET: /Index/- public ActionResult Index()
@H_404_24@ {- return View("~/Views/Index.cshtml");
@H_404_24@ }- }
@H_404_24@}
当项目运行起来后,直接将页面导航至Index.chtml。所以到这里大家应该能想来Silverlight就寄宿在这个界面上。我们看看代码是如何寄宿的。
- @{
@H_404_24@ Layout = null;- }
@H_404_24@ <!DOCTYPE html>- <html>
@H_404_24@ <head>- <title>Index1</title>
@H_404_24@ <style type="text/css">- html, body
@H_404_24@ {- height: 100%;
@H_404_24@ overflow: auto;- }
@H_404_24@- body
@H_404_24@ {- padding: 0;
@H_404_24@ margin: 0;- }
@H_404_24@- #silverlightControlHost
@H_404_24@ {- height: 100%;
@H_404_24@ text-align: center;- }
@H_404_24@ </style>- <script type="text/javascript" src="../../Silverlight.js"></script>
@H_404_24@ <script type="text/javascript">- function onSilverlightError(sender, args) {
@H_404_24@ var appSource = "";- if (sender != null && sender != 0) {
@H_404_24@ appSource = sender.getHost().source;- }
@H_404_24@- var errorType = args.ErrorType;
@H_404_24@ var iErrorCode = args.ErrorCode;- @H_404_24@ if (errorType == "ImageError" || errorType == "MediaError") {
- return;
@H_404_24@ }- @H_404_24@ var errMsg = "Silverlight 应用程序中未处理的错误 " + appSource + "\n";
- @H_404_24@ errMsg += "代码: " + iErrorCode + " \n";
- errMsg += "类别: " + errorType + " \n";
@H_404_24@ errMsg += "消息: " + args.ErrorMessage + " \n";- @H_404_24@ if (errorType == "ParserError") {
- errMsg += "文件: " + args.xamlFile + " \n";
@H_404_24@ errMsg += "行: " + args.lineNumber + " \n";- errMsg += "位置: " + args.charPosition + " \n";
@H_404_24@ }- else if (errorType == "RuntimeError") {
@H_404_24@ if (args.lineNumber != 0) {- errMsg += "行: " + args.lineNumber + " \n";
@H_404_24@ errMsg += "位置: " + args.charPosition + " \n";- }
@H_404_24@ errMsg += "方法名称: " + args.methodName + " \n";- }
@H_404_24@- 引发新错误(errMsg);
@H_404_24@ }- </script>
@H_404_24@ </head>- <body>
@H_404_24@ <form id="form1" runat="server" style="height: 100%">- <div id="silverlightControlHost">
@H_404_24@ <object data="data:application/x-silverlight-2," type="application/x-silverlight-2"- width="100%" height="100%">
@H_404_24@ <param name="source" value="/ClientBin/MISInfoManage.xap" />- <param name="onError" value="onSilverlightError" />
@H_404_24@ <param name="background" value="white" />- <param name="minRuntimeVersion" value="4.0.50826.0" />
@H_404_24@ <param name="autoUpgrade" value="true" />- <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration: none">
@H_404_24@ <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="获取 Microsoft Silverlight"- style="border-style: none" />
@H_404_24@ </a>- </object>
@H_404_24@- </div>
@H_404_24@ </form>- </body>
@H_404_24@ </html>
关键就在于Silverlight.js的引用,以及object中param的设置。在这里需要注意的是这个source属性,它的value值是指xap包所在的位置,如下所示,位于ClientBin下。
光凭这些代码还不能完成寄宿,我们还需要在MISInfomanage.Web.Host上点击右键,选择Silverlight Applications。添加要寄宿的Silverlight项目,如下
OK,这样就完成了一个Silverlight项目的寄宿。谈完这个,我们再回到Server端机构的解析,我就以一个登陆流程来解释。首先用户在登录界面点击登陆按钮,调用Login/GetUser/{id}。
- using System;
@H_404_24@ using System.Collections.Generic;- using System.Linq;
@H_404_24@ using System.Web;- using System.Web.Mvc;
@H_404_24@- namespace MISInfoManage.Web.Controllers
@H_404_24@{- using Server.Business.Interface;
@H_404_24@ using Server.Domain;- using Server.Model.edmx;
@H_404_24@ public class LoginController : Controller- {
@H_404_24@ //- // GET: /Login/
@H_404_24@ IUserBiz userBiz;- public LoginController(IUserBiz userBiz)
@H_404_24@ {- this.userBiz = userBiz;
@H_404_24@ }- @H_404_24@ public JsonResult GetUser(string id)
- {
@H_404_24@ Users user = userBiz.GetUser(id);- return Json(user, JsonRequestBehavior.AllowGet);
@H_404_24@ }- }
@H_404_24@}
这个时候,程序要调用UserBiz,UserBiz要调用UserService,UserService要调用UserRepository,而UserRepository又继承BaseRepository<T>,在每一层调用都有IOC存在。IOC怎么工作呢,先看看Global.asax.cs。
- protected void Application_Start()
@H_404_24@ {- AreaRegistration.RegisterallAreas();
@H_404_24@ IoCHelper.InitializeWith(new DependencyResolverFactory());- ControllerBuilder.Current.SetControllerFactory(new ResolverControllerFactory().GetControllerFactory());
@H_404_24@ RegisterRoutes(RouteTable.Routes);- }
Controller的创建已经交由DependencyResolverFactory这个依赖注入工厂接手,所以我们看到Controller中的IUserBiz而不是UserBiz。那么这个注入在哪里配置着呢?在Host项目下,如下图所示
就是这个Unity.Login.Config。因为目前我只做了个登陆功能,所以在这里只有一个Config文件。那么Unity是怎么读取这个配置文件的呢?我们看看Server端IOC项目下有个UnityContainerBuilder类,他是负责创建依赖注入容器的。在它里面有这么一段代码
- private IEnumerable<string> GetConfigFilePaths()
@H_404_24@ {- string path = AppSettingsHelper.GetString("UnityConfigPath", "Config/Unity");// 默认值为"Config/Unity"
@H_404_24@ return Directory.GetFiles(PathHelper.LocateServerPath(path))- .Where(fullName => Path.GetExtension(fullName).Equals(".config", StringComparison.CurrentCultureIgnoreCase));
@H_404_24@ }
就是这个方法来抓取所有的注入配置文件。我们来看看注入配置文件。
- <?xml version="1.0"?>
@H_404_24@ <configuration>- <configSections>
@H_404_24@ <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>- </configSections>
@H_404_24@ <unity>- <typeAliases>
- <typeAlias alias="IUserRepository" type="Server.Repository.Interface.IUserRepository, Repository" />
- <typeAlias alias="UserRepository" type="Server.Repository.Implement.UserRepository, Repository" />
@H_404_24@ <typeAlias alias="IUserService" type="Server.Application.Interface.IUserService,Application" />- <typeAlias alias="UserService" type="Server.Application.Implement.UserService, Application" />
@H_404_24@ <typeAlias alias="IUserBiz" type="Server.Business.Interface.IUserBiz,Business" />- <typeAlias alias="UserBiz" type="Server.Business.Implement.UserBiz, Business" />
@H_404_24@- <typeAlias alias="IDatabaseFactory" type="Server.Domain.IDatabaseFactory, Domain" />
@H_404_24@ <typeAlias alias="DatabaseFactory" type="Server.Domain.DatabaseFactory,Domain" />- <!--控制器 开始-->
@H_404_24@ <typeAlias alias="IControllerFactory" type="System.Web.Mvc.IControllerFactory, System.Web.Mvc,Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />- <typeAlias alias="UnityControllerFactory" type="Server.IOC.IocResolver.UnityControllerFactory,IOC" />
@H_404_24@ <typeAlias alias="LoginController" type="MISInfoManage.Web.Controllers.LoginController, MISInfoManage.Web.Host" />- <!--控制器 结束-->
@H_404_24@ </typeAliases>- @H_404_24@ <containers>
- <container name="ContainerEF">
@H_404_24@ <!--登录-->- <register type="IDatabaseFactory" mapTo="DatabaseFactory">
@H_404_24@ <constructor>- <param name="connectionName">
@H_404_24@ <value value="MISInfoEntities"></value>- </param>
@H_404_24@ </constructor>- </register>
@H_404_24@- <register type="IUserRepository" mapTo="UserRepository">
@H_404_24@ <constructor>- <param name="dataBaseFactory">
@H_404_24@ <dependency type="DatabaseFactory"></dependency>- </param>
@H_404_24@ </constructor>- </register>
@H_404_24@- <register type="IUserService" mapTo="UserService">
@H_404_24@ <constructor>- <param name="dataContext">
@H_404_24@ <dependency type="DatabaseFactory"></dependency>- </param>
@H_404_24@ <param name="userRepository">- <dependency type="UserRepository"></dependency>
@H_404_24@ </param>- </constructor>
@H_404_24@ </register>- @H_404_24@ <register type="IUserBiz" mapTo="UserBiz">
- <constructor>
@H_404_24@ <param name="userService">- <dependency type="UserService"></dependency>
@H_404_24@ </param>- </constructor>
@H_404_24@ </register>- @H_404_24@ <register type="IControllerFactory" mapTo="UnityControllerFactory">
- </register>
@H_404_24@- <register type="LoginController" mapTo="LoginController">
@H_404_24@ <constructor>- <param name="userBiz">
@H_404_24@ <dependency type="UserBiz"></dependency>- </param>
@H_404_24@ </constructor>- </register>
@H_404_24@ </container>- </containers>
@H_404_24@ </unity>- </configuration>
@H_404_24@
<typeAlias alias="IUserService" type="Server.Application.Interface.IUserService,Application" />
这个配置是一个声明别名的配置,type制定其所在的完整命名空间,所在程序集。类似于这样的配置都一样。我们重点看ContanerEF中的配置。首先是IDatabaseFactory的配置。DataBaseFactory的代码如下
- public class DatabaseFactory : Idisposable, IDatabaseFactory
@H_404_24@ {- DbContext dbContext;
@H_404_24@ string connectionName;- public DatabaseFactory(string connectionName)
@H_404_24@ {- this.connectionName = connectionName;
@H_404_24@ }- public DbContext Get()
@H_404_24@ {- dbContext = new DbContext(connectionName);
@H_404_24@ return dbContext;- }
@H_404_24@ public void dispose()- {
@H_404_24@ if (dbContext != null)- {
@H_404_24@ dbContext.dispose();- }
@H_404_24@ }- }
在UserRepository中我们需要给BaseRepository传递一个databaseFactory,用来创建对应的DBContext。如下所示
在这里,因为我们Login界面所用到的DbContext的链接字符串如下
- <connectionStrings>
@H_404_24@ <add name="applicationservices"- connectionString="data source=.\sqlEXPRESS;Integrated Security=sspI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
@H_404_24@ providerName="System.Data.sqlClient" />- <add name="MISInfoEntities" connectionString="Metadata=res://*/edmx.MISInfo.csdl|res://*/edmx.MISInfo.ssdl|res://*/edmx.MISInfo.msl;provider=System.Data.sqlClient;provider connection string="data source=ZZCYIC6VXOK5UXO\MSsqlSERVER08;initial catalog=MISInfo;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
@H_404_24@ </connectionStrings>
所以注入的时候,我们把DatabaseFactory构造函数中的connectionName注入为MISInfoEntities。对于其他的注入参数,都是采用构造函数注入。相信大家看看就清楚了。在最后我们看看BaseRepository的构造函数。
由此我们可以看出,如果你的Databasefactory的connectionstring是MISInfoEntities的话,那么BaseRepository接收到的将会是MISInfoEntities(继承DbContext)。如果是PersonEntities,那么Databasefactory的Get方法获取的是PersonEntities(继承DbContext)。这样就可以根据配置文件很容易的更换数据源,或者有时候叫工作单元,从而实现低耦合和控制反转。好了,最后我们一起看看我设计的主界面。
ok,最后我们看看设计代码。
- <UserControl
@H_404_24@ x:Class="MISInfoManage.MainPage"- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@H_404_24@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"- xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
@H_404_24@ xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"- xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@H_404_24@ mc:Ignorable="d"- xmlns:source="clr-namespace:MISInfoManage.Resources">
@H_404_24@ <UserControl.Resources>- <source:MainPageResource x:Key="Resource"></source:MainPageResource>
@H_404_24@ </UserControl.Resources>- <Grid x:Name="LayoutRoot" Style="{StaticResource LayoutRootGridStyle}" >
@H_404_24@ <Grid.Background>- <ImageBrush ImageSource="/MISInfoManage;component/Images/windows.jpg" Stretch="UniformToFill"></ImageBrush>
@H_404_24@ </Grid.Background>- <Grid.RowDeFinitions>
@H_404_24@ <RowDeFinition Height="*"></RowDeFinition>- <RowDeFinition Height="Auto"></RowDeFinition>
@H_404_24@ </Grid.RowDeFinitions>- <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Grid.Row="0">
@H_404_24@ <StackPanel Orientation="Vertical" HorizontalAlignment="Left">- <Border CornerRadius="5" BorderBrush="Aqua" BorderThickness="0" MouseMove="Border_MouseMove" MouseLeave="Border_MouseLeave">
@H_404_24@ <StackPanel Orientation="Vertical" x:Name="StackPanel1" Margin="10,10,10">- <Image Source="/MISInfoManage;component/Images/Navigation/UserManage.png" Width="60"/>
@H_404_24@ <TextBlock x:Name="Tb_UserManage" Text="{Binding Tb_UserManage,Source={StaticResource Resource}}" Style="{StaticResource MainPageTextStyle}"/>- </StackPanel>
@H_404_24@ </Border>- <Border CornerRadius="5" BorderBrush="Aqua" BorderThickness="0" MouseMove="Border_MouseMove" MouseLeave="Border_MouseLeave">
@H_404_24@ <StackPanel Orientation="Vertical" Margin="10,10">- <Image Source="/MISInfoManage;component/Images/Navigation/ArchiveInfo.png" Width="60"/>
@H_404_24@ <TextBlock x:Name="Tb_ArchiveManage" Text="{Binding Tb_ArchiveManage,0">- <Image Source="/MISInfoManage;component/Images/Navigation/SystemManage.png" Width="60"/>
@H_404_24@ <TextBlock x:Name="Tb_SystemManage" Text="{Binding Tb_SystemManage,Source={StaticResource Resource}}" Style="{StaticResource MainPageTextStyle}"/>- </StackPanel>
@H_404_24@ </Border>- </StackPanel>
@H_404_24@ </ScrollViewer>- <Button x:Name="BtnLoginInfo" BorderBrush="AliceBlue" Grid.Row="1" Height="30" BorderThickness="1" Background="AliceBlue" FontSize="16"></Button>
@H_404_24@ </Grid>- </UserControl>
- using System;
@H_404_24@ using System.Collections.Generic;- using System.Linq;
@H_404_24@ using System.Net;- using System.Windows;
@H_404_24@ using System.Windows.Controls;- using System.Windows.Documents;
@H_404_24@ using System.Windows.Input;- using System.Windows.Media;
@H_404_24@ using System.Windows.Media.Animation;- using System.Windows.Navigation;
@H_404_24@ using System.Windows.Shapes;- using MISInfoManage.Resources;
@H_404_24@- namespace MISInfoManage
@H_404_24@{- public partial class MainPage : UserControl
@H_404_24@ {- public MainPage()
@H_404_24@ {- InitializeComponent();
@H_404_24@ }- @H_404_24@ public MainPage(string userName):this()
- {
@H_404_24@ this.BtnLoginInfo.Content = string.Format(MainPageResource.Btn_LoginInfo,userName);- }
@H_404_24@- private void Border_MouseMove(object sender, MouseEventArgs e)
@H_404_24@ {- Border border = sender as Border;
@H_404_24@ border.Background = new SolidColorBrush(Colors.White);- border.Background.Opacity = 0.5;
@H_404_24@ border.BorderThickness = new Thickness(1);- }
@H_404_24@- private void Border_MouseLeave(object sender, MouseEventArgs e)
@H_404_24@ {- Border border = sender as Border;
@H_404_24@ border.Background = new SolidColorBrush();- border.BorderThickness = new Thickness(0);
@H_404_24@ }- }
@H_404_24@}
好了,本节到此结束,下一节重点进入增删改查,数据验证,双向,单向绑定。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。