我希望 TFS 2010 在发生特定工作流转换时运行一些自定义代码。那可能吗?
我找到了有关自定义操作的文档,这似乎是可以自动触发工作项转换的操作(我说对了吗?)我还找到了与构建相关的自定义活动。但是没有什么能满足这个特殊要求——我错过了什么吗?
谢谢你的帮助!
这是非常可行的。
它是如此可行,以至于有很多方法可以做到。我的最爱之一是制作服务器端插件。(注意,这仅适用于 TFS 2010)
这些博客文章显示了基础知识:
这是我从开源项目TFS Aggregator修改的一些代码:
public class WorkItemChangedEventHandler : ISubscriber
{
/// <summary>
/// This is the one where all the magic starts. Main() so to speak.
/// </summary>
public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs,
out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
{
statusCode = 0;
properties = null;
statusMessage = String.Empty;
try
{
if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
{
// Change this object to be a type we can easily get into
WorkItemChangedEvent ev = notificationEventArgs as WorkItemChangedEvent;
// Connect to the setting file and load the location of the TFS server
string tfsUri = TFSAggregatorSettings.TFSUri;
// Connect to TFS so we are ready to get and send data.
Store store = new Store(tfsUri);
// Get the id of the work item that was just changed by the user.
int workItemId = ev.CoreFields.IntegerFields[0].NewValue;
// Download the work item so we can update it (if needed)
WorkItem eventWorkItem = store.Access.GetWorkItem(workItemId);
if ((string)(eventWorkItem.Fields["State"].Value) == "Done")
{
// If the estimated work was changed then revert it back.
// We are in done and don't want to allow changes like that.
foreach (IntegerField integerField in ev.ChangedFields.IntegerFields)
{
if (integerField.Name == "Estimated Work")
{
eventWorkItem.Open();
eventWorkItem.Fields["Estimated Work"].Value = integerField.OldValue;
eventWorkItem.Save();
}
}
}
}
}
}
return EventNotificationStatus.ActionPermitted;
}
public string Name
{
get { return "SomeName"; }
}
public SubscriberPriority Priority
{
get { return SubscriberPriority.Normal; }
}
public WorkItemChangedEventHandler()
{
//DON"T ADD ANYTHING HERE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING.
//TFS DOES NOT LIKE CONSTRUCTORS HERE AND SEEMS TO FREEZE WHEN YOU TRY :(
}
public Type[] SubscribedTypes()
{
return new Type[1] { typeof(WorkItemChangedEvent) };
}
}
/// <summary>
/// Singleton Used to access TFS Data. This keeps us from connecting each and every time we get an update.
/// </summary>
public class Store
{
private readonly string _tfsServerUrl;
public Store(string tfsServerUrl)
{
_tfsServerUrl = tfsServerUrl;
}
private TFSAccess _access;
public TFSAccess Access
{
get { return _access ?? (_access = new TFSAccess(_tfsServerUrl)); }
}
}
/// <summary>
/// Don't use this class directly. Use the StoreSingleton.
/// </summary>
public class TFSAccess
{
private readonly WorkItemStore _store;
public TFSAccess(string tfsUri)
{
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri(tfsUri));
_store = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));
}
public WorkItem GetWorkItem(int workItemId)
{
return _store.GetWorkItem(workItemId);
}
}
这是我的单例模式的示例
public class TFSSingleton
{
private static TFSSingleton _tFSSingletonInstance;
private TfsTeamProjectCollection _teamProjectCollection;
private WorkItemStore _store;
public static TFSSingleton Instance
{
get
{
if (_tFSSingletonInstance == null)
{
_tFSSingletonInstance = new TFSSingleton();
}
return _tFSSingletonInstance;
}
}
public TfsTeamProjectCollection TeamProjectCollection
{
get { return _teamProjectCollection; }
}
public WorkItemStore RefreshedStore
{
get
{
_store.RefreshCache();
return _store;
}
}
public WorkItemStore Store
{
get { return _store; }
}
private TFSSingleton()
{
NetworkCredential networkCredential = new NetworkCredential("pivotalautomation", "*********", "***********");
// Instantiate a reference to the TFS Project Collection
_teamProjectCollection = new TfsTeamProjectCollection(new Uri("http://********:8080/tfs/**********"), networkCredential);
_store = (WorkItemStore)_teamProjectCollection.GetService(typeof(WorkItemStore));
}
}
以下是它的引用方式。
WorkItemTypeCollection workItemTypes = TFSSingleton.Instance.Store.Projects[projectName].WorkItemTypes;