Обновить
87.61

C# *

Объектно-ориентированный язык программирования

Сначала показывать
Порог рейтинга
Уровень сложности

DuoCode: транслируем C# в JavaScript

Время на прочтение10 мин
Охват и читатели26K
Есть такой язык программирования, который называется C#. И есть очень много разработчиков, которым он очень нравится. А ещё есть такой язык программирования, который называется JavaScript. Как-то так сложилось, что он нравится далеко не всем C#-разработчикам. А теперь представьте ситуацию: есть заядлый C#-разработчик. Он очень любит C#, все-все проекты на нём пишет. Но судьба распорядилась так, что ему понадобилось написать клиентское веб-приложение. Знаете, такое, чтобы пользователю не нужно было себе ничего скачивать и устанавливать, чтобы он мог просто открыть любой браузер в любой операционной системе на любом устройстве — а приложение уже там. И вот тут у нашего лирического героя возникла проблема: вроде бы JavaScript идеально подходит для этой задачи, но вот писать на нём отчего-то не очень хочется. К счастью, в современном мире существует много языков, которые транслируются в JavaScript (всякие TypeScript, CoffeScript и тысячи других). Но наш разработчик оказался очень упрямым: он упорно не хочет изменять своему любимому C# с «вражескими» технологиями.

К счастью для него, счастливое будущее уже практически наступило. Есть такой проект, который называется DuoCode. Он умеет транслировать C#-код в JavaScript. Пока он в состоянии beta, но у него уже весьма неплохо получается: поддерживаются нововведения C# 6.0, Generic-типы, Reflection, структуры и LINQ, а отлаживать итоговый JavaScript можно на исходном C#. Давайте посмотрим внимательнее, что же представляет из себя продукт.

Читать дальше →

Триггерные рассылки

Время на прочтение11 мин
Охват и читатели9.6K
Последнее время в Email-маркетинге все чаще используются автоматические рассылки определенным группам потребителей. Типичные задачи:
  • поздравить с днем рожденья
  • позвать на сайт, если потребитель на него долго не заходил
  • сделать персонализированное предложение (делим потребителей на сегменты и рассылаем каждому сегменту свое письмо)

В этой статье мы расскажем, как мы решали эту задачу — от написания каждой отдельной рассылки разработчиком с нуля 3 года назад, до заведения рассылок менеджером через веб-интерфейс в настоящее время. Рассказ может быть интересен не только тем, кто занимается Email-маркетингом но и вообще всем, кому приходится реализовывать периодическое выполнение сложных операций над определенными выборками потребителей (знаю, что звучит очень абстрактно, но в итоге именно такую абстрактную задачу нам и пришлось решить).

Первые реализации

3 года назад подобные задачи возникали крайне редко и мы каждый раз реализовывали их с нуля. При этом возникали одни и те же вопросы:
  1. Как помечать потребителей, которым мы уже отправили это письмо?
  2. Как максимально быстро обработать всех потребителей и при этом не тормозить работу сайтов (которые обращаются к тем же записям в БД)?

На первый вопрос ответ для нас был очевиден: в нашей системе сохраняется информации о всех значимых действиях, выполняемых потребителем (вход на сайт, изменение персональных данных) или над ним (розыгрыш приза, отправка уведомления). Кроме того, мы используем действия для разнообразных технических пометок потребителей. Так что при отправке автоматической рассылки, мы также решили выдавать потребителю особое действие-маркер, в качестве пометки, что эта автоматическая рассылка ему уже была отправлена. Чтобы повторно не отправлять рассылку, к условию рассылки всегда добавляется условие “у потребителя нет действия-маркера”.

На втором вопросе мы набили множество шишек, связанных с блокировками в БД, и в итоге пришли к следующему шаблону:
  1. Отправка рассылок идет из windows-сервиса, который периодически проверяет не появилось ли новых потребителей, подходящих под условия.
  2. В сервисе первым шагом делается один запрос к БД с уровнем изоляции Read Uncommitted. Этот запрос вытаскивает Id всех потребителей, которым надо отправить письмо. Из-за низкого уровня изоляции такой запрос не накладывает блокировок на записи в БД и, как следствие, крайне слабо влияет на работу сайта. Однако он не гарантирует чистоту данных и их надо повторно проверить с более высоким уровнем изоляции.
  3. После того, как мы вытащили Id потребителей, для каждого потребителя мы выполняем отдельную транзакцию с уровнем изоляции Serializable. В этой транзакции мы заново проверяем подходит ли потребитель под условия и если да, отправляем ему письмо и выдаем действие-маркер. Так как мы обрабатываем каждого потребителя в отдельной транзакции, блокировки накладываются только на данные одного потребителя и на работу остальных потребителей не влияют. Так как такая транзакция очень короткая, у потребителя, которому отправляют письмо, также не будет особых проблем, если он в это время ходит по сайту. Уровень изоляции транзакции должен быть именно Serializable, чтобы ненароком не отправить одно письмо дважды, или не отправить письмо тому потребителю, который внезапно перестал подходить под условия. Хотя, если мы гарантируем, что отправка одной и той же рассылки может идти только из одного потока и с одного сервера, а также забьем на небольшую вероятность того, что одному потребителю могут отправится две рассылки с взаимоисключающими условиями, то можно использовать и Read Committed транзакцию.

Само собой после реализации нескольких рассылок по этому шаблону, мы решили вынести шаблонный код. Для этого был создан класс BatchMailing, и для каждой новой рассылки мы создавали и регистрировали в специальном реестре его наследника. В наследнике необходимо было перегрузить следующие свойства и методы:
  • шаблон действия-маркера (раньше мы называли шаблон типом действия: думаю, для разработчиков это более понятный термин), которое выдается при отправке письма
  • метод, отправляющий письмо
  • метод, выполняющий дополнительные действия (например, вместе с отправкой поздравления с днем рожденья, мы можем выдавать потребителю баллы на счет)
  • метод, который формирует Expression<Func<Customer, bool>>, проверяющий, что потребитель подходит под условие

Свойство и первые два метода никогда никаких проблем не вызывали, но вот составить Expression было довольно таки не просто. Этот Expression использовался два раза — сначала в Read Uncommitted запросе, чтобы вытащить Id потребителей, а затем в Serializable транзакции, чтобы повторно проверить подходит ли потребитель под условие. Его было нужно написать так, чтобы Linq to SQL смог его транслировать в T-SQL. Условия могли быть довольно сложными и в них всегда возникали проблемы. Ни одну рассылку нельзя было завести не написав на нее кучку тестов. Кроме того, для отправки СМС и email мы завели разных промежуточных наследников от BatchMailing. Когда же нам надо было отправить и email и СМС, приходилось копипастить. У меня были идеи как это исправить, но так как автоматические рассылки клиенты просили не так уж и часто, это была низкоприоритетная задача.

Замена наследования композицией

2 года назад при разработке очередной рекламной кампании клиент попросил сделать ему сразу 8 разных автоматических рассылок. При этом частично условия в рассылках повторялись. Тут уже не оставалось сомнений, что больше так жить нельзя, и я взялся за переписывание нашей архитектуры. Для того чтобы справится со всеми описанными выше проблемами достаточно было применить наш любимый прием: замену наследования композицией. Этот прием настолько много раз нам помогал, что я советую использовать композицию вместо наследования везде, где это возможно (ну или как минимум рассматривать такой вариант). Если вы создаете базовый абстрактный класс с мыслью “для каждой конкретной задачи у меня будет наследник перегружающий методы и свойства”, сразу спрашивайте себя “а почему бы мне вместо этого не регистрировать для каждой задачи экземпляр класса, передавая ему разные настройки”. И только если вы уверены, что композиция здесь не подходит, используйте наследование. Если подходит и то и то, всегда склоняйтесь к композиции — так получается гораздо более гибкая и понятная архитектура.

В нашей ситуации:
  • вместо перегрузки свойства, возвращающего шаблон действия-маркера, это свойство проставляется экземпляру класса
  • вместо перегрузки методов отправляющих письма/смс и выполняющих дополнительную логику, у экземпляра класса проставляется произвольная операция, которую нужно совершить над потребителем. При этом операция может быть комбинацией из других операций
  • вместо перегрузки метода формирующего Expression, экземпляру класса проставляется условие. При этом условия можно комбинировать через И/ИЛИ

Так как кроме отправки рассылок эта сущность теперь может выполнять любые произвольные операции над потребителем, рассылкой ее называть некорректно. Фактически это класс который делает какую-то абстрактную работу над заданной выборкой потребителей. Не придумав ничего лучше, мы стали называть это триггерами (в маркетинге их примерно так и называют, так что название неплохое). Меня, честно говоря, немного пугало то, что я ввел в систему крайне абстрактную сущность, которую можно назвать DoSomeWorkOnSomeCustomers. Но никакого смысла в специализации триггеров не было, так что я решил над этим не заморачиваться, и в принципе больших проблем с пониманием, что такое триггер, у клиентов не возникает.

Регистрация триггера выглядела примерно следующим образом:
Add(new Trigger(“Приглашение на сайт для пришедших через канал one-to-one”)
{
	MarkerActionTemplateSystemName = “InvitationMarker”,
	TriggerAction = new TriggerActionCombination(
		new GeneratePasswordForCustomerTriggerAction(),
		new SendEmailTriggerAction(“InvitationMailing”)),
	TriggerCondition = new AndTriggerConditionSet(
		new CustomerHasSubscripionCondition(),
		new CustomerHasEmailTriggerCondition(),
		new CustomerHadFirstActionOverChannelCondition(“OneToOne”)),
});

Интерфейс TriggerAction’а крайне прост:
public interface ITriggerAction
{
	void Execute(
		ModelContext modelContext, // класс для работы с БД 
		Customer customer);
}

Базовый класс для условий триггера выглядит следующим образом:
public class TriggerCondition
{
	private readonly Func<ModelContext, Expression<Func<Customer, bool>>> triggerExpressionBuilder;

	public TriggerCondition(Func<ModelContext, Expression<Func<Customer, bool>>> triggerExpressionBuilder)
	{
		if (triggerExpressionBuilder == null)
			throw new ArgumentNullException("triggerExpressionBuilder");

		this.triggerExpressionBuilder = triggerExpressionBuilder;
	}

	public Expression<Func<Customer, bool>> GetExpression(ModelContext modelContext)
	{
		return triggerExpressionBuilder(modelContext, brand);
	}

	// Используется в Read Uncommitted транзакции для получения спиcка Id потребителей, подходящих под условие
	public IQueryable<Customer> ChooseCustomers(ModelContext modelContext, IQueryable<Customer> customers)
	{
		if (modelContext == null)
			throw new ArgumentNullException("modelContext");
		if (customers == null)
			throw new ArgumentNullException("customers");

		var expression = GetExpression(modelContext);
		return customers.Where(expression).ExpandExpressions();
	}

	// Используется в Serializable транзакции, для проверки, что потребитель все еще подходит под условие
	public bool ShouldTrigger(ModelContext modelContext, Customer customer)
	{
		if (modelContext == null)
			throw new ArgumentNullException("modelContext");
		if (customer == null)
			throw new ArgumentNullException("customer");

		var expression = GetExpression(modelContext);
		// Можно бы было просто вызывать expression.Evaluate(customer),
		// но тогда для сложных условий выполнилось бы несколько запросов в БД вместо одного
		return modelContext.Repositories.Get<CustomerRepository>().Items
			.Where(aCustomer => aCustomer == customer)
			.Where(aCustomer => expression.Evaluate(aCustomer))
			.ExpandExpressions()
			.Any();
	}
}
Для часто используемых условий мы создавали наследников от TriggerCondition, в которых строился конкретный Expression в зависимости от переданных в конструктор параметров.

Все, надоело, сами заводите свои триггеры

С использованием архитектуры, описанной выше, мы заводили триггер менее чем за пол часа, за счет комбинирования уже написанных условий и TriggerAction’ов. Однако и этого нам было мало. Следующим шагом мы захотели полностью исключить разработчиков из процесса заведения триггеров. Причем как это делать в общих чертах я понял уже через пару месяцев после реализации предыдущей версии архитектуры. Условия триггеров были один в один похожи на фильтры, которые мы используем в админке. Наша система фильтров позволяет описывать сложные условия, включая запросы к связанным сущностям, а также позволяет комбинировать их через И/ИЛИ. Фильтр формирует Expression, с помощью которого уже можно отфильтровывать сущности в БД. И для всего этого уже был написан UI и сериализация. Оставалось лишь добавить пару фильтров, которые часто нужны для триггеров, но не имели смысла при обычной работе со списком потребителей (например: “с действия прошло N дней”). Для TriggerAction’ов надо было написать UI и структуру для хранения их в БД, но тут тоже в общем все было понятно. Однако оставались еще небольшие вопросы, над которым пришлось поломать голову:
  • отсылку любого письма мы к этому времени стали регистрировать как действие, и действие-маркер стало лишним — мы и так могли определить, кому мы отправляли письмо, и вообще хотелось бы избавиться от выдачи лишних действий везде, где это было возможно
  • кроме простых триггеров, которые выполняли определенный набор операций один раз над каждым потребителем, у нас появились периодические триггеры. Надо было придумать как это все перенести в БД и при этом позволить использовать произвольные маркеры
  • маркетологи придумывают триггеры не отдельно друг от друга, а в качестве цепочек, в которых есть как триггеры так и операции, выполняемые потребителем на сайте (письмо с предложением зайти на сайт и что-то сделать → потребитель выполняет несколько операций на сайте → начисляются бонусные баллы и посылается письмо об этом). Хотелось бы если и не реализовать это сразу, то оставить задел на будущее, чтобы было не сложно описывать зависимости между триггерами и операциями
Все эти три проблемы связаны с тем, как мы определяем выполнился ли триггер над потребителем или нет. Если заводить для каждого триггера и операции на сайте свой маркер, задача сильно упрощается, но плодить лишние действия в системе очень не хотелось. Была даже идея заставлять менеджеров составлять фильтр таким образом, чтобы он полностью отвечал за то, можно ли сейчас выполнить действие над потребителем (и соответственно частота повторения триггера описывалась бы условием в фильтре), однако данный подход слишком уж располагает к ошибкам. После долгих мучительных размышлений мне все-таки пришла идея, как отслеживать выполнение триггеров без дополнительных сущностей и без усложнения работы менеджера.

Нужно больше Expression’ов

Так как триггер выполняет абстрактный шаг операции (бывший TriggerAction) над потребителем, причем почти всегда этот шаг операции уникален (например, определенное письмо отсылается или определенный приз выдается только из этого триггера), то в этот шаг можно вынести логику проверяющую выполнился ли он. Так как в триггере может быть несколько шагов операции, то менеджеру надо будет выбрать какой из них является маркером (проверять выполнение каждого шага не имеет смысла). Однако просто, реализовать в шаге операции метод, возвращающий Expression<Func<Customer,bool>> нельзя, так как пришлось бы в каждом шаге операции формировать один Expression для одноразовых триггеров, другой для периодических. Тут нас спасает то, что практически любая операция над пользователем в нашей системе выдает ему действие. Соответственно шаг операции может отфильтровать те действия, которые были выдан им. Большинство шагов операции выдают конкретное действие и для них метод, формирующий Expression для фильтрации действий, выглядит вот так:
public sealed override Expression<Func<CustomerAction, bool>> GetIsMarkerExpression(ModelContext modelContext)
{
	return action => action.ActionTemplateId == ActionTemplateId;
}

Но, например, у шага, выдающего приз, он выглядит следующим образом:
public override Expression<Func<CustomerAction, bool>> GetIsMarkerExpression(ModelContext modelContext)
{
	IQueryable
Читать дальше →

Заполнение текстовых шаблонов данными на основе модели. Реализация на .NET с использованием динамических функций в байт-коде (IL)

Время на прочтение19 мин
Охват и читатели11K

Пролог


Недавно возникла задача массовой рассылки писем, текст которых формируется на основе шаблона, в котором помимо статического содержимого есть информация о получателе и фрагменты текста. В моем случае это шаблон автоматического оповещения подписчиков о публикации новых статей, соответственно в нем есть обращение к адресату и красиво оформленная ссылка на публикацию.

Сразу возник вопрос — как это реализовать? На ум приходили различные решения, начиная от задания в шаблоне неких константных значений, которые бы заменялись на данные модели, и заканчивая полноценными вьюхами Razor (сайт построен на MVC 5).

После непродолжительной битвы с самим собой, я пришел к выводу, что эту достаточно распространенную задачу пора решить раз и навсегда, и что ее решение должно быть не очень сложным (т.е. не должно зависеть от библиотек, не входящих в состав .NET Framework 4), но при этом достаточно функциональным, чтобы решать поставленную задачу и иметь запас по расширяемости.

В данной статье я расскажу о решении на основе генератора байт-кода, которое удовлетворяет этим требованиям, а также прокомментирую наиболее интересные фрагменты кода.

Если вас интересует только шаблонизатор, ссылочки ниже:

Исходные коды шаблонизатора (Genesis.Patternizer) и тестовой консоли в проекте на SourceForge: https://sourceforge.net/projects/open-genesis/?source=navbar
Или в архиве одним файлом: Patternizer.zip

Читать дальше →

Добавляем MVP в игры на Unity3D

Время на прочтение5 мин
Охват и читатели22K
image Всем доброго времени суток. В данной статье хотел бы рассказать о том как можно применить шаблон MVP в процессе разработки игр на платформе Unity3D. Использование этого шаблона может способствовать упорядочению кода и улучшению структуры проекта. Стоит сразу отметить, что в статье не дается детального описания самого шаблона, а предполагается наличие у читателя базовых знаний о нем.

Как мы все с Вами знаем, MVP — это шаблон призванный отделить презентационную логику от логики приложения. В случае Unity3D, представлением может быть GameObject с набором прикрепленных к нему компонентов, необходимых для реализации презентационной логики ( в том числе и компонент самой презентационной логики — MonoBehaviour имплементирующий соответствующий интерфейс представления (View)).
Читать дальше →

Consulo: Code Coverage, Unity3D и прочие изменения

Время на прочтение3 мин
Охват и читатели10K
Для тех кто пропустил мои посты:Consulo — это форк IntelliJ IDEA Community Edition, который имеет поддержку .NET(C# на текущий момент, и на этот сектор пока идет большой акцент), Java.

В этой мини-статье я поделюсь с вами с тем, что удалось сделать за последние 2 месяца.





Читать дальше →

Управление удалённым IIS

Время на прочтение8 мин
Охват и читатели15K

Вступление


Некоторое время назад мне была поставлена задача найти оптимальный способ программного управления удалённым IIS и реализовать его в виде некоего модуля. Задача интересная, с множеством трудностей, поэтому хочется поделиться своим опытом.

Вот список основных требований к реализуемому модулю:
  • Возможность выполнения основных операций с IIS:
    • создание сайта
    • создание virtual application
    • создание virtual directory
    • настройка bindings для сайтов, включая установку сертификатов SSL
    • создание пулов приложений с детальной настройкой
  • Поддержка параллельной работы с несколькими IIS на разных серверах фермы
  • Поддержка IIS версии 8.0 (более ранние версии поддерживать не нужно).

Одним словом, модуль должен был уметь практически всё, что можно сделать через IIS Manager.
Как реализовывался данный функционал

Continuous Delivery: Продолжение

Время на прочтение7 мин
Охват и читатели19K
2 года назад в статье «Continuous Delivery & Sitecore: наша реализация» я представлял нашу систему автоматической доставки веб-приложений основанных на Sitecore. Это были первые маленькие шаги в направлении мира полной автоматизации.
Читать дальше →

Интересные моменты работы Linq to Sql

Время на прочтение14 мин
Охват и читатели17K
Прошло уже больше года с моего предыдущего поста на похожую тему. За это время мы как-то не приблизились к переходу на Entity Framework (по текущей легенде, мы перейдём, когда появится стабильная версия EF 7), ну а у меня накопилось некоторое количество опыта, которым я бы хотел поделиться. Думаю, что эта статья будет интересна тем, кто, как и мы, до сих пор пользуются этой в общем-то неплохой, но позабытой Microsoft технологией.

DbType


Указание подсказки DbType (за исключением enum'ов, об этом ниже) не является обязательным для свойств сущностей в Linq 2 Sql. И уж точно не стоит указывать неправильный DbType. Например, не стоит, если в базе колонка имеет тип nvarchar(50), указывать Linq 2 Sql, что колонка имеет тип nchar(50). И особенно не стоит так делать, если это поле является дискриминатором, как в следующем примере:

	[Table(Name = "directcrm.OperationSteps")]
	[InheritanceMapping(Code = "", Type = typeof(OperationStep), IsDefault = true)]
	// ...
	[InheritanceMapping(Code = "ApplySegment", Type = typeof(ApplySegmentOperationStep))]
	public class OperationStep : INotifyPropertyChanging, INotifyPropertyChanged, IValidatable
	{

		// Некоторое количество кода
		...

		[Column(Storage = "type", DbType = "nchar(50) NOT NULL", CanBeNull = false, IsDiscriminator = true)]
		public string Type
		{
			get
			{
				return type;
			}
			set
			{
				if ((type != value))
				{
					SendPropertyChanging();
					type = value;
					SendPropertyChanged();
				}
			}
		}
	}

Читать дальше →

Опыт решения проблемы созданием OLAP-куба, используя С#

Время на прочтение3 мин
Охват и читатели14K

Предыстория


Хотел бы поделиться своим небольшим опытом, который я приобрел на работе в одном государственном учреждении. Как я туда попал — не важно, но это важно знать, т.к. это налагает свою специфику на условия, в которых приходилось решать поставленную задачу. Стоит так же отметить, что основные мои знания и скудный опыт в программировании относятся к .Net технологиям.

Описание задачи: существует и по сей день созданная лет 10 назад информационная система, которая собирает отчетную информацию, по разным, периодически изменяющимся статистическим показателям, от разных филиалов организации по региону. Инфраструктура информационного взаимодействия системы указана на рисунке ниже. Показатели в DW описаны неявно.

image
Читать дальше →

Семинар по анатомии CLR и .Net Framework. Roslyn, CoreCLR, CoreFx, Nitra, RyuJIT

Время на прочтение4 мин
Охват и читатели4.5K

03-04 Апреля в Москве и 29-30 мая — в Санкт-Петербурге пройдет серия семинаров CLRium. У данного семинара нет определенной целевой аудитории, мы рады всем. И начинающим свою карьеру, разработчикам, и махровым, повидавшим виды, архитекторам.

Как люди и хотят, у нас будут не просто технические доклады, без воды и маркетинга. У нас будет много тем, одна из которых — настоящая разминка для мозгов. Мы будем по дампам памяти понимать как устроена CLR и как с ней взаимодействовать не привычным для всех способом — напрямую.

У нас будет:
  • Максимально глубокие, отборные доклады по редко-раскрываемым вопросам
  • Целый вечер, посвященный исключительно ядру .Net. Как с ним работать «без перчаток», напрямую, со структурами в памяти, без рефлексии.


Чем мы гордимся:
  • Наш материал не встретишь в сети Интернет: он полностью авторский
  • Материал освещает самые интересные области .Net, которые почему-то не покрыты материалом.
  • Мы не берем лишних денег с вас и потому у нас — самая дешевая конференция и всех существующих. 2,000 рублей за два дня — такого не предлагает никто. Это ведь как в магазин сходить.

Читать дальше →

Поиск в ширину (BFS) на С#

Время на прочтение4 мин
Охват и читатели51K
Сразу скажу, что статья больше подойдёт людям, желающим познакомиться с поиском в ширину, и новичкам, осваивающим программирование. К тому же, когда мне понадобился этот метод, я нигде не нашёл наглядного рабочего примера на C#.

Устно об алгоритме:

Разберём алгоритм на произвольном графе (для простоты примера рёбра не имеют вес).

Последовательность алгоритма заключается в следующим:

1. Выбирается произвольно вершина графа (отмечается серым).
2.Последовательно рассматриваются вершины (так же отмечаются серым), связанные с нашей первой вершиной (после этого она становится не серой, а чёрной).
3. Выполняется пункт 2 для отмеченных (серых) вершин до тех пор, пока все вершины не будут закрашены чёрным.


Читать дальше →

Breeze Server — разграничиваем доступ к объектам при помощи атрибутов

Время на прочтение12 мин
Охват и читатели8.6K

В прошлой статье Breeze.js + Entity Framework + Angular.js = удобная работа с сущностями базы данных прямо из браузера мы рассмотрели создание простейшего приложения, где делали выборки и сохраняли данные в базе прямо из javascript в браузере. Конечно же первыми у читателей возникли вопросы о безопасности. Поэтому сегодня мы рассмотрим, как можно организовать разграничение доступа. Для этого мы немного доработаем наше приложение из прошлой статьи так, чтобы можно было при помощи атрибутов раздать определённые права доступа на добавление, удаление, изменение и просмотр данных определённым пользователям или ролям.
Читать дальше →

Пишем с нуля квест на ASP.NET 5 (vNext) и Angular.js

Время на прочтение8 мин
Охват и читатели47K
С выходом новой версии ASP.NET хочется попробовать, какая же она на практике. А для того, чтобы не писать еще один чатик\соц. сеть\блог..., для пилотного проекта выберем логический квест — и фреймворк посмотрим, и поиграть можно.
Результат:
сорсы на гитхабе для тех, кому интересно поиграться с новым ASP.NET
линк на квест для тех, кому интересно что получилось или потратить свое время на еще один логический квест.

Читать дальше →

Ближайшие события

Что Mono 4.0.0 нам готовит

Время на прочтение2 мин
Охват и читатели23K


В последнее время многие обсуждают недавние открытие CoreCLR и CoreFX от Microsoft. Напомню, что ядро CLR и реализация базовых классов .NET у нас теперь открытые, кроссплатформенные и распространяются под MIT. Таким образом, вы можете собрать свою собственную версию рантайма, которая будет работать под Windows, Linux и Mac. И многих терзал вопрос: а что же теперь будет с Mono? Недавно появились черновики Mono 4.0.0 Release Notes, из которых мы можем узнать о будущих планах компании Xamarin. Итак, сегодня в номере:
  • Adoption of Microsoft’s open source code
  • Floating point optimizations
  • We dropped support for the 2.0, 3.5 and 4.0 assemblies
  • Updated IKVM
Обсудим грядущие изменения чуть подробней.
Читать дальше →

DevCon Digest #1. Погружаемся в .NET

Время на прочтение4 мин
Охват и читатели18K


Привет, Хабр! Пока мы во всю готовимся к нашей ежегодной большой конференции DevCon, мы решили, что разработчикам, которые будут смотреть и слушать доклады конференции и общаться с экспертами, хорошо бы тоже углубить и освежить свои знания до конфернции.

Поэтому мы решили делать еженедельные тематичные подборки материалов по одному из направлений конференции, собрав в одном месте недавние новости, новые учебные материалы, анонсы параллельных мероприятий и другие полезные ресурсы.
Читать дальше →

Защита игр и мобильных приложений от взлома для чайников (Unity, C#, Mono)

Время на прочтение8 мин
Охват и читатели75K
Всем снова здравствуйте! Дошли руки написать крутую статью на весьма важную тему для разработчиков игр. Итак, поговорим о защите ваших драгоценных игр и приложений, которые вы пилите на Unity в надежде заработать на буханку хлеба, от взлома злобными школьниками. Почему школьниками? Потому что надежной на 100% защиты априори быть не может. И кто захочет, все равно взломает. Вопрос лишь в том, сколько времени и сил он на это потратит. И как любят шутить безопасники — терморектальный криптоанализ никто не отменял.

Итак, в статье я постараюсь максимально доступно рассказать о 3 аспектах (и конечно, предложу реализацию):
  • защита данных приложения (сейвов)
  • защита памяти приложения
  • защита внутриигровых покупок (Google Play)

image
Читать дальше →

Ядро .Net (GC, JIT, interop, ...) в Open Source

Время на прочтение5 мин
Охват и читатели37K
Мы рады сообщить что CoreCLR теперь находится на github и теперь вы имеете доступ ко всем его исходным кодам. CoreCLR является средой исполнения .NET Core, выполняя такие функции как сборку мусора или компиляции в конечный машинный код. .Net Core – это модульная реализация .Net, которая может быть использована как база для огромного количества сценариев, масштабы которых варьируются от простых консольных утилит до веб-приложений, хостящихся в облаке. Чтобы понять, чем отличается .Net Core от .Net Framework, посмотрите на пост «Введение в .Net Core»

Теперь вы можете скачивать исходники CoreCLR, бранчеваться, и делать pull requests, также вы можете компилировать его прямо на своем ПК. Мы выпустили полную и актуальную реализацию CoreCLR, которая включает RyuJIT, .Net GC, родной Interop и множество других компонент .Net runtime. Данный релиз следует тем же принципам, что и все наши последние релизы библиотек, вышедших в open-source: сделать весь .Net Framework open sourced.

Сегодня ядро .Net компилируется и отрабатывает (видимо имеется в виду CI) на Windows. Мы добавим имплементации для специфических для Mac и Linux платформенных вещей в ближайшие пару месяцев. Также мы уже имеем некоторый специфический для Linux код в .Net Core, однако мы только начали портировать с Windows на остальные платформы. Напротив, мы хотели открыть исходные тескты с самого начала, чтобы вы вместе с нами пропутешествовали бы к другим платформам, возможно, внося свой вклад.
Читать дальше →

Что нового в C# 6.0?

Время на прочтение4 мин
Охват и читатели148K
image

Microsoft выпустила предварительную версию Visual studio 2015 и .Net 4.6 для разработчиков. В новом C# 6.0 несколько новых возможностей, которые могут облегчить кодинг.

В этой статье рассмотрены новые возможности языка C# 6.0. Скачать новую VS можно по ссылке:
Microsoft Visual Studio Ultimate 2015 Preview

Инициализация свойств со значениями


В C# 6.0 мы можем инициализировать свойства со значениями, написав справа от них их значение. Это поможет избежать ошибки с null и пустыми значениями свойства.

Раньше:


public int Id { get; set; }
public string FirstName { get; set; }

Теперь:


public int Id { get; set; } = 1001;
public string FirstName { get; set; } = "Srinivas";
Читать дальше →

70 эпичных докладов, сумасшедшая agile атмосфера и 1000+ соратников ждут тебя на AgileDays’15!

Время на прочтение1 мин
Охват и читатели3.3K
Главное ежегодное событие Agile отрасли – AgileDays’15 пройдет с 19 по 20 марта 2015 года в Центре Международной Торговли на Краснопресненской набережной, 12. В этом году мероприятие будет еще масштабней.

Традиционно программа AgileDays’15 включает в себя Keynotes от зарубежных Agile-гуру, множество тематических докладов, воркшопов и ежегодно собирает в дни мероприятия более чем 1000 человек.

В 5 параллельных потоках будут обсуждаться методологии, применяемые для гибкого управления процессами – Scrum, Kanban, Lean и т.д., продуктовая разработка, инженерные практики и DevOps и многое другое.

За формирование программы отвечает Программный комитет, также можно подать заявку на выступление с докладом.
Читать дальше →

Руководство к Car Tutorial (Unity3d) часть 3 из 3

Время на прочтение18 мин
Охват и читатели30K
Часть 1
Часть 2

Прежде чем начнем, хочу предложить скрипты переписанные на C#. т.к половина скриптов на JS я решил переписать их под C# (мне C# роднее). Скачать

Так же идет активный «разбор» проекта для начинающих «Project: Survival shooter», видеоуроки представлены в следующем Плэйлисте, дополнительные видеоуроки к Survival shooter. Лично выражаю благодарность этому каналу, за их не легкий труд.

p.s в конце этого руководства есть видео обзор в котором на примерах идет сравнение двух реализованных методов управления автомобилем.

Итак, приступим к изучению нашего руководства.

Часть 3: Под капотом


Мы уже видели, как собрать рабочую машину из 3D-модели, скриптов и встроенных компонентов. Мы также познакомились с публичными переменными и как они могут быть использованы для тонкой настройки автомобиля.
Читать дальше →

Вклад авторов