10.24.2009
asp.net, website, objectdatasource
В asp.net есть такой тип проекта WebSite. Он отличается от WebApplication тем, что проектный сайт не создается, любой попавшый в папку файл добавляется в сайт, и самое главное - сайт не собирается в отдельную сборку. На продакшн сайт можно добавлять новые странички не компилируя их (ну есть конечно же предкомпиляция сайта, но см. далее). Каждая страничка компилируется через iis сервер в собственную сборку с рандомным именем. Как это разруливает сервер - загадка.
Для простой логики где все находится в пределах одной страницы все окей, а вот когда требуется вызвать код находящийся на другой страничке - начинаются проблемы: одна страничка ничего не знает о другой (т.к. находится в собственной сборке). Обычное решение - выносить такой нужный код в отдельную собственную сборку, типа библиотеки, закинуть ее в bin директорию сайта, подключать ее в страничках сайта и использовать в коде. Хорошо то оно хорошо. А что делать если ну никак не хочется выносить одну единственную функцию в библиотеку, код которой нужен только на одной единственной страничке?
Пример - нужно реализовать bind грида через object data source, и не через что-либо иное (такое может понадобится для использования фишек грида типа редактирования, удаления в табличке, сортировки, пейджинга и т.п.). Проблема сводится к тому что в SelectMethod нужно написать имя метода, в SelectParameters - параметры, а в TypeName - полное название типа где находится метод. А класс лежит в своей собственной сборке, а имя генерируется рандомно. Единственное решение проблемы - динамически заполнять поле TypeName на этапе загрузки страницы. Вот финальный код:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="myprojectclass.aspx.cs" Inherits="myprojectclass" %>
<asp:GridView ID="gridView1" runat="server" DataSourceID="objectDataSource1" AutoGenerateColumns="True" />
<asp:ObjectDataSource ID="objectDataSource1" runat="server" SelectMethod="GetData" TypeName="" ></asp:ObjectDataSource>
public partial class myprojectclass : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// ...
objectDataSource1.TypeName = String.Format("{0}, {1}", this.GetType().FullName, this.GetType().Assembly);
gridView1.DataBind();
}
public System.Collections.Generic.List<DataItem> GetData() {
// ...
}
}
Повторюсь - это будет работать в пределах одной страницы, код другой странички получить не получится. Только через собственную сборку. Выводы: 1. никогда не использовать WebSite 2. использовать только WebApplication - так как все получается логично и понятно 3. По возможности никогда не использовать ASP.NET - есть другие более удобные инструментарии веб-разработки
10.18.2009
Подсветка синтаксиса в блоге
<link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushXml.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCpp.js' type='text/javascript'/>
<script type='text/javascript'>
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.1.364/scripts/clipboard.swf';
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.defaults['gutter'] = true;
SyntaxHighlighter.all();
</script>
Тем самым мы добавили нужные стили (у меня используется дефолтный, но вообще доступно несколько) и скрипты (здесь я добавил html, cpp, c#), настроили компоненту должным образом. За подробными комментариями по назначению, списку всех параметров и всех возможных скриптов - на сайт производителя. Потом в html-код сообщения добавляем
<pre class="brush: cpp; toolbar: true;">
#include <iostream>
int main() {
std::cout << "hello" << std::endl;
}
</pre>
P.S. Главное не забывать ескейпить символы...
10.15.2009
Индусы среди нас
class Item {
public static void UpdateItem(Item _item) {
// ...
}
}
Item it;
// ...
Item.UpdateItem(it);
Попахивает безграммотностью. Не логично использовать статический метод который принимает экземпляр собственного класса. Я попросил человечка избавиться от статического метода. Код был переписан вот в это:
class Item {
public void UpdateItem(Item _item) {
// ...
}
}
Item it;
// ...
new Item().UpdateItem(it);
Да, оказывается у некоторых в крови индусские гены и они в тайне по ночам молятся шестируким богам. И почему нельзя сделать вот так, по простому:
class Item {
public void UpdateItem() {
// ...
}
}
Item it;
// ...
it.UpdateItem();
8.19.2009
Не вероятно, но факт
1.18.2009
How to Use Constraints in Generics
class Abc<T> where T : IDisposable
{ ... }
Ну это понятно, теперь разберемся с самими ограничениями, с первыми двумя - все и так понятно, а вот на последние два авторы как-то забыли объяснить и дать пример.
1. parameterless constructor - требование безпараметрического конструктора. По-суть очень полезно, если внутри своего класса вы хотите создавать новые экземпляры обобщенного класса. Все очень просто, нужно написать new(). Кстати без данного ограничения вы не сможете написать T it = new T()... :)
class Abc<T> where T : new()
{
public void DoSmth()
{
T it = new T();
}
}
2. Reference or value type. Тоже может быть очень полезным - так как мы можем полностью отсечь применения типа Abc<int> и т.д. Тут сложнее: для referenced type должно идти ключевое слово class, для value type - ключевое слово struct.
class Abc<T> where T : class
{ ... }
class Cba<T> where T : struct
{ ... }
Честно говоря, когда я узнал что так можно делать - у меня был шок. Сразу же разрешилось несколько проблем в проектах :) Надеюсь кому-нибудь это тоже пригодится.
